Typography
A semantic typography primitive for headings, body copy, and inline code.
Usage
import { Typography } from '@hareui/vue'Build better interfaces
Typography that stays semantic
Composable by default
Small heading
HeroUI Typography uses React Aria Components Text as the primitive, with semantic typography types and render-prop polymorphism.
Smaller muted body copy for secondary descriptions.
pnpm add @heroui/react<script setup lang="ts">import { Typography } from '@hareui/vue'</script><template> <div class="flex max-w-xl flex-col gap-4"> <Typography type="h1">Build better interfaces</Typography> <Typography type="h2">Typography that stays semantic</Typography> <Typography type="h3">Composable by default</Typography> <Typography type="h4">Small heading</Typography> <Typography> HeroUI Typography uses React Aria Components Text as the primitive, with semantic typography types and render-prop polymorphism. </Typography> <Typography color="muted" type="body-sm"> Smaller muted body copy for secondary descriptions. </Typography> <Typography type="code">pnpm add @heroui/react</Typography> </div></template>Anatomy
Typography maps visual type values to semantic elements by default.
<Typography type="h1">Heading</Typography>typepicks both the visual style and, unlessasis set, the rendered element:h1–h6→<h1>–<h6>,body/body-sm/body-xs→<p>,code→<code>.proseswitches to a rich-content container (<div data-slot="prose">): children are plain HTML and receive HeroUI's default typography rhythm instead of thetypestyles.type,align,color,weightandtruncateare ignored in this mode.
ui keys: base, prose.
Examples
Scale
Build better interfaces
Built for the intelligence age
Pricing on your terms
Apply to the startup program
Card titles
Smaller feature headers
Primary body text used across documentation, marketing copy, and descriptions.
Secondary body, table cells, navigation, and sidebar items.
Captions, badges, helper text, and fine print.
pnpm add @heroui/react<script setup lang="ts">import { Typography } from '@hareui/vue'const scale = [ { label: 'h1', meta: '36px / 600 / 1.11 / tight', sample: 'Build better interfaces', type: 'h1' as const }, { label: 'h2', meta: '30px / 600 / 1.17 / tight', sample: 'Built for the intelligence age', type: 'h2' as const }, { label: 'h3', meta: '24px / 600 / 1.25 / tight', sample: 'Pricing on your terms', type: 'h3' as const }, { label: 'h4', meta: '20px / 600 / 1.33 / tight', sample: 'Apply to the startup program', type: 'h4' as const }, { label: 'h5', meta: '18px / 600 / 1.39 / tight', sample: 'Card titles', type: 'h5' as const }, { label: 'h6', meta: '16px / 600 / 1.50 / tight', sample: 'Smaller feature headers', type: 'h6' as const }, { label: 'body', meta: '16px / 400 / 1.75', sample: 'Primary body text used across documentation, marketing copy, and descriptions.', type: 'body' as const }, { label: 'body-sm', meta: '14px / 400 / 1.50', sample: 'Secondary body, table cells, navigation, and sidebar items.', type: 'body-sm' as const }, { label: 'body-xs', meta: '12px / 400 / 1.25', sample: 'Captions, badges, helper text, and fine print.', type: 'body-xs' as const }, { label: 'code', meta: '14px / mono', sample: 'pnpm add @heroui/react', type: 'code' as const },]</script><template> <div class="flex w-full flex-col divide-y divide-border"> <div v-for="row in scale" :key="row.label" class="grid grid-cols-[160px_1fr] items-center gap-8 py-5"> <div class="flex shrink-0 flex-col gap-0.5"> <span class="text-sm font-semibold text-foreground">{{ row.label }}</span> <span class="text-xs whitespace-nowrap text-muted">{{ row.meta }}</span> </div> <Typography :type="row.type">{{ row.sample }}</Typography> </div> </div></template>Primitives
Dashboard
Convenience primitives are thin wrappers over Typography, so you can choose explicit composition without learning a second styling system.
Paragraph supports base, sm, and xs sizes.
Typography.Code <script setup lang="ts">import { Typography } from '@hareui/vue'</script><template> <div class="flex max-w-xl flex-col gap-4"> <Typography type="h1"> Dashboard </Typography> <Typography> Convenience primitives are thin wrappers over Typography, so you can choose explicit composition without learning a second styling system. </Typography> <Typography color="muted" type="body-sm"> Paragraph supports base, sm, and xs sizes. </Typography> <Typography type="code"> Typography.Code </Typography> </div></template>Typography.Heading level={1..6}maps totype="h1"throughtype="h6".Typography.Paragraph size="base" | "sm" | "xs"maps totype="body","body-sm"and"body-xs".Typography.Codemaps totype="code".Typography.Prosemaps to theproseprop, which styles rich content passed as regular HTML children.
Prose
Prose title
Prose is for authored content where the markup is already semantic and HeroUI applies the default typography rhythm.
Section title
Inline code like render receives the same code treatment as the Typography primitive.
<script setup lang="ts">import { Typography } from '@hareui/vue'</script><template> <Typography class="flex max-w-xl flex-col gap-3" prose> <h1>Prose title</h1> <p> Prose is for authored content where the markup is already semantic and HeroUI applies the default typography rhythm. </p> <h2>Section title</h2> <p> Inline code like <code>render</code> receives the same code treatment as the Typography primitive. </p> </Typography></template>Render Props
H1 visual style, h2 semantic element
The render prop can swap the underlying element while preserving HeroUI props and styles.<script setup lang="ts">import { Typography } from '@hareui/vue'</script><template> <div class="flex max-w-xl flex-col gap-4"> <Typography as="h2" type="h1"> H1 visual style, h2 semantic element </Typography> <Typography as="span"> The render prop can swap the underlying element while preserving HeroUI props and styles. </Typography> </div></template>Use the as prop when you need to customize the rendered element.
Customization
Tailwind CSS
Changelog
Faster search results
Queries now return in under 200ms thanks to an improved index.
<script setup lang="ts">import { Typography } from '@hareui/vue'</script><template> <div class="flex max-w-md flex-col gap-2 rounded-xl border border-border/80 bg-surface-secondary p-4"> <Typography class="text-xs font-medium tracking-wide text-accent uppercase" type="body-xs"> Changelog </Typography> <Typography class="font-semibold tracking-tight text-foreground" type="h4"> Faster search results </Typography> <Typography class="text-sm leading-relaxed text-muted" type="body-sm"> Queries now return in under 200ms thanks to an improved index. </Typography> </div></template>Global theme override
Override the typography theme app-wide with createHareUI:
app.use(createHareUI({
ui: {
typography: {
variants: {
type: {
h1: { base: 'font-extrabold tracking-tight' },
code: { base: 'rounded-md bg-default-100 font-mono dark:bg-default-50/20' },
},
},
},
},
}))Styling Reference
Each rendered element carries the same data-slot string as HeroUI (typography for the default mode, prose for prose mode), so selectors translate 1:1.
ui key | data-slot | Description |
|---|---|---|
base | typography | Base typography primitive |
prose | prose | Rich prose container |
HeroUI follows BEM for its modifier classes (HareUI renders utilities, not BEM classes, so style through class, ui or createHareUI):
.typography--h1through.typography--h6,.typography--body,.typography--body-sm,.typography--body-xs,.typography--code→ thetypeprop.typography--align-start,--align-center,--align-end,--align-justify→ thealignprop.typography--color-default,--color-muted→ thecolorprop.typography--weight-normal,--weight-medium,--weight-semibold,--weight-bold→ theweightprop.typography--truncate→ thetruncateprop
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as | AsTag | Component | - | The element or component to render as, overriding the element implied by type
(equivalent to HeroUI's render prop). |
type | "body" | "h2" | "h3" | "code" | "h1" | "h4" | "h5" | "h6" | "body-sm" | "body-xs" | "body" | Semantic typography style. |
align | "center" | "start" | "end" | "justify" | "start" | Text alignment. |
color | "default" | "muted" | "default" | Text color. |
weight | "bold" | "medium" | "normal" | "semibold" | - | Font weight override. |
truncate | boolean | false | Truncates the text to one line with ellipsis. |
prose | boolean | false | Renders a rich prose container instead: children are plain HTML (headings, paragraphs,
links, lists, code, …) and receive HeroUI's default typography rhythm. type, align,
color, weight and truncate are ignored in this mode. |
ui | ComponentSlots<{ slots: { base: string; prose: string[]; }; variants: { type: { h1: { base: string; }; h2: { base: string; }; h3: { base: string; }; h4: { base: string; }; h5: { base: string; }; h6: { base: string; }; body: { base: string; }; 'body-sm': { base: string; }; 'body-xs': { base: string; }; code: { base: string; }; }; align: { start: { base: string; }; center: { base: string; }; end: { base: string; }; justify: { base: string; }; }; color: { default: { base: string; }; muted: { base: string; }; }; weight: { normal: { base: string; }; medium: { base: string; }; semibold: { base: string; }; bold: { base: string; }; }; truncate: { true: { base: string; }; }; }; defaultVariants: { type: string; align: string; color: string; }; }> | - | Per-slot class overrides. |
Slots
| Slot | Props | Description |
|---|---|---|
default | any | Typography content. |





