Display

text-2xl (24px)

Page title

text-xl (17px)

Section title

text-lg (15px)

Heading

text-base (13px)

Body

text-base (13px)

Body sm

text-sm (12px)

Body secondary

text-base (13px)
Monospacetext-sm (12px)
Monospace secondarytext-sm (12px)
text-base (13px)

Error

text-base (13px)
import { Text } from "@cloudflare/kumo";

export function TextVariantsDemo() {
  return (
    <div className="grid w-full grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="display" as="h1">
          Display
        </Text>
        <Text variant="mono-secondary">text-2xl (24px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="page-title" as="h2">
          Page title
        </Text>
        <Text variant="mono-secondary">text-xl (17px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="section-title" as="h3">
          Section title
        </Text>
        <Text variant="mono-secondary">text-lg (15px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="heading" as="h4">
          Heading
        </Text>
        <Text variant="mono-secondary">text-base (13px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text>Body</Text>
        <Text variant="mono-secondary">text-base (13px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text size="sm">Body sm</Text>
        <Text variant="mono-secondary">text-sm (12px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="secondary">Body secondary</Text>
        <Text variant="mono-secondary">text-base (13px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="mono">Monospace</Text>
        <Text variant="mono-secondary">text-sm (12px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="mono-secondary">Monospace secondary</Text>
        <Text variant="mono-secondary">text-sm (12px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="success">Success</Text>
        <Text variant="mono-secondary">text-base (13px)</Text>
      </div>
      <div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
        <Text variant="error">Error</Text>
        <Text variant="mono-secondary">text-base (13px)</Text>
      </div>
    </div>
  );
}

Installation

Barrel

import { Text } from "@cloudflare/kumo";

Granular

import { Text } from "@cloudflare/kumo/components/text";

Usage

import { Text } from "@cloudflare/kumo";

export default function Example() {
  return <Text>Your content here</Text>;
}

Heading variants

Heading variants are role-based. Reach for the one that describes what the text is, not how big you want it:

  • variant="display" — hero / prominent moments (24px semibold)
  • variant="page-title" — the single title of a page or dialog (17px medium)
  • variant="section-title" — card / panel / section heading (15px medium)
  • variant="heading" — inline / row / list-item heading (13px medium)

heading is the small, most-used one — reach for it before adding extra weight or size to body text.

Semantic HTML

The variant prop controls visual styling only—it does not determine the HTML element rendered. Heading variants require the as prop to avoid silently excluding real section headings from the document outline. Body and monospace variants have sensible defaults (<p> and <span> respectively) and accept as optionally.

// Heading variants REQUIRE `as` — TypeScript will flag usages missing it
<Text variant="display">Welcome</Text> // Doesn't compile

// Real section headings (contribute to the document outline)
<Text variant="display" as="h1">Welcome</Text>
<Text variant="page-title" as="h1">Account settings</Text>
<Text variant="section-title" as="h2">General</Text>
<Text variant="heading" as="h3">API tokens</Text>

// Decorative heading-styled text that is NOT a section heading
<Text variant="display" as="span">Big card label</Text>

// Visually one size, semantically another
<Text variant="display" as="h3">Visually large, but semantically h3</Text>

The as prop accepts: "h1" through "h6", "p", and "span". Body variants default to "p", monospace variants default to "span", and heading variants have no default — you must choose explicitly.

Restrictions

The size prop is intentionally restricted to the body, secondary, success, and error variants.

<Text size="sm">Body</Text>
<Text variant="secondary" size="sm">Body secondary</Text>
<Text variant="success">Success</Text>
<Text variant="error">Error</Text>

Monospace variants (mono and mono-secondary) always render at 12px and do not accept a size prop.

<Text variant="mono">Monospace</Text>

Heading variants (display, page-title, section-title, heading) don’t accept size — the size is part of the role.

The bold prop follows the same shape: it applies only to copy variants (body, secondary, success, error), where it bumps weight to font-medium (500) for inline emphasis. Heading variants already carry their role’s weight, and monospace stays regular by design — both type bold as never so consumers get a compile error rather than a silent no-op. For structural hierarchy inside a document outline reach for variant="heading" instead of bold.

<Text bold>Important detail</Text>
<Text variant="secondary" bold>Muted but bumped</Text>

Deprecated variants

The numeric heading names still work but emit a warning in development. Migrate call sites to the role-based names:

  • heading1display
  • heading2page-title
  • heading3section-title

Truncate

Use the truncate prop to clip overflowing text with an ellipsis. This adds truncate min-w-0 classes, which is useful when Text is inside a flex or grid container.

This is a long piece of text that will be truncated with an ellipsis when it overflows its container.

import { Text } from "@cloudflare/kumo";

export function TextTruncateDemo() {
  return (
    <div className="w-64 rounded-lg border border-kumo-hairline bg-kumo-base p-4">
      <Text truncate>
        This is a long piece of text that will be truncated with an ellipsis
        when it overflows its container.
      </Text>
    </div>
  );
}
<Text truncate>This is a long piece of text that will be truncated...</Text>

API Reference

PropTypeDefaultDescription
variant"display" | "page-title" | "section-title" | "heading" | "heading1" | "heading2" | "heading3" | "body" | "secondary" | "success" | "error" | "mono" | "mono-secondary""body"Text style variant. Heading variants (role-based, weight-first hierarchy): - `"display"` — Hero / prominent moments (24px semibold) - `"page-title"` — The single title of a page or dialog (17px medium) - `"section-title"` — Card / panel / section heading (15px medium) - `"heading"` — Inline / row / list-item heading (13px medium) Body variants: - `"body"` — Default body text (13px) - `"secondary"` — Muted text for secondary information - `"success"` — Success state text - `"error"` — Error state text - `"mono"` — Monospace text for code - `"mono-secondary"` — Muted monospace text Deprecated (use the role-based names above): - `"heading1"` → use `"display"` - `"heading2"` → use `"page-title"` - `"heading3"` → use `"section-title"`
size"sm" | "base" | "xs" | "lg""base"Text size (only applies to body/secondary/success/error variants). - `"sm"` — 12px (caption / helper text) - `"base"` — 13px (default body) - `"xs"` — **Deprecated.** Use `"sm"` instead. - `"lg"` — **Deprecated.** Use `"base"` instead.
boldboolean-Bumps body copy weight to `font-medium` (500). Only applies to copy variants (`body`, `secondary`, `success`, `error`); heading variants already carry their role's weight and disallow this prop at the type level. For structural hierarchy inside a document outline reach for `variant="heading"` instead — `bold` is for inline emphasis.
truncateboolean-Whether to truncate overflowing text with an ellipsis. Adds `truncate min-w-0` classes.
as"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "label" | "dt" | "dd" | "li" | "figcaption" | "legend" | "pre" | "code" | "em" | "strong" | "small" | "abbr" | "time"-The HTML element to render. Accepts headings (`"h1"`–`"h6"`), block text (`"p"`, `"pre"`), inline text (`"span"`, `"code"`, `"em"`, `"strong"`, `"small"`, `"abbr"`, `"time"`), form-related (`"label"`, `"legend"`), list/definition (`"dt"`, `"dd"`, `"li"`), and `"figcaption"`. - **Required** for heading variants (`"display"`, `"page-title"`, `"section-title"`, `"heading"`) — pick the element that reflects this text's place in the document outline, or `"span"` for decorative heading-styled text that is not a section heading. - **Optional** for body variants (defaults to `"p"`) and monospace variants (defaults to `"span"`).
childrenReactNode-Text content.