PageHeader
The title, description and main actions at the top of a page.
Templates
Manage email templates for your project.
<template> <PageHeader title="Templates" description="Manage email templates for your project."> <template #actions> <Button>Create template</Button> </template> </PageHeader></template>Props
| Name | Type | Default |
|---|---|---|
| title | string | - |
| description | string | - |
Slots
| Name | Description |
|---|---|
| leading | Whatever sits before the title - decorative (an entity glyph) or functional (e.g. a sidebar-collapse toggle). Omit entirely when the page has none. |
| attribute | Exactly one element inline with the title - a status Badge, or a single plain Button. Never more than one, never a Select/Combobox (that's an action, use #actions). |
| description | Overrides the `description` prop. |
| actions | The page's primary action(s), pinned to the header row. |
Guidelines
Do
- Give every page exactly one
PageHeader- it's the page's own identity (what am I looking at, what can I do here), not a repeatable section heading. UsePageSection's own title/description for anything below it. - Reach for the
#descriptionslot, not thedescriptionprop, as soon as the supporting line is more than plain text - a linked PR/repo/category meta row, an inline "edit" affordance, a relative-time-and-author caption. That's the common case in practice, not the exception. - Put the page's primary action (Create, Invite, Export) in
#actions- it stays pinned to the header row regardless of how long the title/description run.
- Use
#leadingfor whatever sits before the title, decorative or functional - an entity glyph, or a control like a sidebar-collapse toggle. - Use
#attributefor exactly one element sitting inline with the title - a statusBadge, or a single plainButton. It's state/identity about what the title names, not an action the user takes. ASelect/Comboboxthat changes that state is an action and belongs in#actionsinstead. - Keep
titleplain text. A linked/breadcrumb-style or edit-in-place title belongs onPageNav's own breadcrumb, not here.
Don't
- Don't put a whole toolbar (filters, search, view toggles) in
#actions- that belongs below the header, closer to the content it filters. - Don't put a status badge in
#actions, or expect a#titleslot to carry it - there is no#titleslot; it gets its own#attributeslot, inline with the title. - Don't put more than one element in
#attribute, or anything besides aBadge/plainButton- a second element or a richer control belongs in#actions.
- Don't reach for
PageNavas this component's precedent - those are the sticky top-bar chrome aboveUDashboardPanel's body;PageHeaderlives inside the body, below it.
Examples
All slots filled
Leading control, a status badge in #attribute next to the title, a composed description row, and an actions cluster - a select/combobox belongs in #actions, a status badge never does.
Passwordless login rollout
In review<template> <PageHeader title="Passwordless login rollout"> <template #leading> <IconButton icon="i-lucide-panel-left-close" variant="ghost" aria-label="Collapse sidebar" /> </template> <template #attribute> <Badge variant="warning">In review</Badge> </template> <template #description> <div class="flex flex-wrap items-center gap-2"> <Button variant="plain" size="xs" to="https://github.com" target="_blank" trailing-icon="i-lucide-arrow-up-right">PR #482</Button> <span>Authentication</span> <span>CWE-287</span> </div> </template> <template #actions> <Button variant="outline">Edit</Button> <IconButton icon="i-lucide-ellipsis" variant="outline" aria-label="More" /> </template> </PageHeader></template>