# Page Header

> A React page header for admin screens: breadcrumb, title with avatar and badges, description, meta, actions that fold into a menu, and tabs.

- Type: React component (Layout)
- Access: Pro (the source needs a Wingo UI Pro plan, see https://wingo-ui.com/pricing)
- Version: 1.2.1
- Install: `npx wingo-ui@latest add page-header`
- Docs: https://wingo-ui.com/components/page-header

## Interaction

Read where you are in the breadcrumb, then act: the primary action always stays in view at the end of the row, and the others fold one by one into a ⋯ menu as the window narrows (they come back when there is room). Actions that return a promise show a spinner until they finish. Tab walks the breadcrumb, the back button, every action and the ⋯ menu (arrow keys and Enter inside it, Escape closes it). With sticky set to condensed, scroll past the header and a glass bar with the title and the primary action slides down under the top bar. On a phone (or whenever the header itself is narrower than 512px, like in a side panel) the actions move under the title: the primary stays as a small button and the rest open from ⋯, as a bottom action sheet on phones (or stack full width with mobileActions set to stack); on phones the title shrinks and a ‹ back link replaces the breadcrumb.

## Installation

```bash
npx wingo-ui@latest add page-header
```

Pro item: run `npx wingo-ui@latest login` once with a Pro account. The CLI adds the files, their dependencies and a version record for updates.

With shadcn: `npx shadcn@latest add @wingo-ui/page-header` (needs the @wingo-ui registry with your API key in components.json)

Files:

- `components/ui/page-header.tsx`

npm dependencies: `npm i motion lucide-react`

Wingo UI dependencies (installed automatically):

- [Avatar](https://wingo-ui.com/components/avatar) ([Markdown](https://wingo-ui.com/components/avatar.md))
- [Breadcrumb](https://wingo-ui.com/components/breadcrumb) ([Markdown](https://wingo-ui.com/components/breadcrumb.md))
- [Button](https://wingo-ui.com/components/button) ([Markdown](https://wingo-ui.com/components/button.md))
- [Dropdown Menu](https://wingo-ui.com/components/dropdown-menu) ([Markdown](https://wingo-ui.com/components/dropdown-menu.md))
- [Skeleton](https://wingo-ui.com/components/skeleton) ([Markdown](https://wingo-ui.com/components/skeleton.md))
- [useMediaQuery](https://wingo-ui.com/components/use-media-query) ([Markdown](https://wingo-ui.com/components/use-media-query.md))
- [useOverflowItems](https://wingo-ui.com/components/use-overflow-items) ([Markdown](https://wingo-ui.com/components/use-overflow-items.md))
- [useScrollState](https://wingo-ui.com/components/use-scroll-state) ([Markdown](https://wingo-ui.com/components/use-scroll-state.md))
- [Motion presets](https://wingo-ui.com/components/motion) ([Markdown](https://wingo-ui.com/components/motion.md))
- [Navigation](https://wingo-ui.com/components/navigation) ([Markdown](https://wingo-ui.com/components/navigation.md))
- [Tones](https://wingo-ui.com/components/tones) ([Markdown](https://wingo-ui.com/components/tones.md))
- [UIProvider](https://wingo-ui.com/components/ui-config) ([Markdown](https://wingo-ui.com/components/ui-config.md))

## Usage

```tsx
import { Pencil, Plus, Trash2 } from "lucide-react"
import { Badge } from "@/components/ui/badge"
import { NavTabs } from "@/components/ui/nav-tabs"
import { PageHeader } from "@/components/ui/page-header"

export function ClientHeader() {
  return (
    <PageHeader
      breadcrumb={[
        { label: "Home", href: "/" },
        { label: "Clients", href: "/clients" },
        { label: "Tech Solutions LLC" },
      ]}
      avatar={{ name: "Tech Solutions LLC" }}
      title="Tech Solutions LLC"
      badges={<Badge tone="success" dot>Active</Badge>}
      description="IT equipment distributor in Austin · EIN 12-3456789"
      meta={[{ label: "Client since Mar 12, 2024" }, { label: "Balance $12,480.00" }]}
      actions={[
        { label: "Edit", icon: <Pencil /> },
        { label: "Delete", icon: <Trash2 />, tone: "danger" },
        { label: "New invoice", icon: <Plus />, primary: true, href: "/invoices/new" },
      ]}
      tabs={
        <NavTabs
          items={[
            { label: "Overview", href: "/clients/tech-solutions" },
            { label: "Invoices", href: "/clients/tech-solutions/invoices", badge: 12 },
          ]}
        />
      }
      sticky="condensed"
    />
  )
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `title?` | `ReactNode` | `""` | The page title, rendered as the page's one <h1> (headingAs changes the element). |
| `headingAs?` | `"h1" \| "h2" \| "h3" \| "div"` | `"h1"` | The title's element. Keep h1 for the page's own header; use h2, h3 or div when the header sits inside a page that already has its h1 (a dialog, a card, a docs preview). |
| `description?` | `ReactNode` | `""` | One or two lines under the title, capped at a readable width. |
| `breadcrumb?` | `BreadcrumbEntry[] \| ReactNode` |  | Entries render a Breadcrumb (it folds the middle when long and becomes a ‹ Parent link on phones). A node renders as is. |
| `backHref?` | `string` | `""` | Adds a back button before the title (through NavLink). Below 640px it replaces the breadcrumb as a ‹ text link. |
| `onBack?` | `() => void` |  | Runs when the back button is pressed; without backHref the back button is a plain button. |
| `backLabel?` | `string` | `"Back"` | The back button's accessible name, and its visible text on phones ("Invoices" reads ‹ Invoices). |
| `icon?` | `ReactNode` |  | An icon in a tinted tile before the title (40px, 48px at lg), colored by tone or color. |
| `avatar?` | `{ src?: string; name: string; radius?: AvatarRadius }` |  | A photo or initials before the title, wins over icon. radius md (default) for companies, full for people. |
| `badges?` | `ReactNode` |  | Status badges after the title; they wrap under it when space runs out. |
| `meta?` | `PageHeaderMeta[] \| ReactNode` |  | Small facts in a wrapping row under the description: { id?, icon?, label }[], with 14px icons. A node renders as is. |
| `actions?` | `PageHeaderAction[] \| ReactNode` |  | { id?, label, icon?, onSelect?, href?, variant?, tone?, primary?, disabled? }[]. The primary one (or the last solid) stays visible, last in the row; the others are outline buttons that fold into ⋯ from the end while they do not fit, and always in the compact layout (header narrower than 512px: phones, side panels). onSelect returning a promise shows the button loading. A node renders as is, without folding. |
| `tabs?` | `ReactNode` |  | NavTabs (or a Tabs list) sitting on the header's bottom border. |
| `children?` | `ReactNode` |  | Extra content between the title row and the tabs, such as filters or a progress bar. |
| `size?` | `"sm" \| "md" \| "lg"` | `"md"` | Title 18 / 24 / 32px (18 / 22 / 26px on phones), with the icon tile and avatar scaled to match. |
| `tone?` | `"neutral" \| "brand" \| "success" \| "warning" \| "danger" \| "info"` | `"neutral"` | The media's color: the icon tile's soft tint, or the avatar's initials when there is no photo (neutral keeps the name-based color). |
| `color?` | `string` | `""` | Any CSS color for the icon tile or the avatar initials; replaces the tone. Leave empty to use the tone. |
| `border?` | `boolean` | `true` | The hairline under the header; tabs sit on it. |
| `loading?` | `boolean` | `false` | Skeletons in the shape of the title, description, meta and actions; the breadcrumb and tabs stay. |
| `maxActions?` | `number` | `0` | The most buttons in the wide row, the primary included (1: only the primary, everything else in ⋯). The rest always open from the ⋯ menu, whatever fits. 0: as many as fit. |
| `mobileActions?` | `"menu" \| "stack"` | `"menu"` | The compact layout (the header narrower than 512px, so every phone): the primary stays as a small button and the rest open from ⋯ (a bottom action sheet on phones), or every action stacks full width (48px, primary on top). |
| `sticky?` | `"none" \| "condensed"` | `"none"` | condensed: once the header scrolls under the top bar, a 48px glass bar with the title and the primary action slides down and pins at top: var(--topbar-offset, 0px). |
| `moreLabel?` | `string` | `"More actions"` | The ⋯ button's accessible name and the phone action sheet's hidden title. |
| `cancelLabel?` | `string` | `"Cancel"` | The cancel row at the bottom of the phone action sheet. |
| `scrollTarget?` | `HTMLElement \| Window \| RefObject<HTMLElement \| null> \| null` |  | What scrolls, for the condensed bar. Default: the nearest ScrollContainerProvider, else the window. |
| `linkComponent?` | `(props: LinkComponentProps) => ReactNode` |  | The router link for link actions, the back link and the breadcrumb. Default: the LinkProvider's. |
| `classNames?` | `Partial<Record<PageHeaderSlot, string>>` |  | Classes for the parts: breadcrumb, row, back, media, heading, title, badges, description, meta, metaItem, actions, more, tabs, condensed, condensedTitle, condensedAction. |

## Examples

- **Minimal**: A title, a description and one primary action.
- **Back button**: backHref instead of a breadcrumb: an icon button on desktop, a ‹ Invoices link on phones. Actions that return a promise load.
- **Settings page**: An icon tile in the brand tone and no actions.
- **Sizes**: sm, md and lg: 18 / 24 / 32px titles with the tile scaled to match.
- **Loading**: Skeletons in the exact shape of the title, description, meta and actions.
- **Compact actions**: Under 512px of width (every phone): the primary stays and the rest open from ⋯ (a sheet on phones), or stack full width.

## See also

- [Breadcrumb](https://wingo-ui.com/components/breadcrumb) ([Markdown](https://wingo-ui.com/components/breadcrumb.md))
- [Nav Tabs](https://wingo-ui.com/components/nav-tabs) ([Markdown](https://wingo-ui.com/components/nav-tabs.md))
- [Large Title Header](https://wingo-ui.com/components/large-title-header) ([Markdown](https://wingo-ui.com/components/large-title-header.md))
- [Topbar](https://wingo-ui.com/components/topbar) ([Markdown](https://wingo-ui.com/components/topbar.md))
- [useOverflowItems](https://wingo-ui.com/components/use-overflow-items) ([Markdown](https://wingo-ui.com/components/use-overflow-items.md))

---

Canonical: https://wingo-ui.com/components/page-header
More components: https://wingo-ui.com/components · Index for agents: https://wingo-ui.com/llms.txt
