Header

Groups the brand, navigation, dropdowns, search, actions and navigation trigger in a top bar.

import { Header } from "@usefragments/ui";Source

Preview

Loading App Bar preview…

import { Button } from '@usefragments/ui';
import { Header } from '@usefragments/ui';

<Header>
  <Header.SkipLink />
  <Header.Brand href="/">Fragments</Header.Brand>

Usage

Use when

  • Top-level navigation for an app or site
  • Inside AppShell.Header
  • Anywhere brand, nav and actions share one row

Avoid when

  • Section headings inside a page (use Main.Header)
  • Toolbars scoped to one panel
  • Sidebar-only navigation (use Sidebar)

Implementation notes

  • Header.Actions sits on the trailing edge on its own; there is no spacer part
  • Omit Header.Brand when the sidebar already shows the product name
  • Header.NavMenu groups related pages behind one trigger; mark the group active when the current page is inside it
  • Inside AppShell or Sidebar.Provider, Header.Trigger opens the sidebar's mobile panel and shows only while the rail is out of view
  • Without a sidebar, open a Drawer of Sidebar.Item rows from Header.Trigger for small screens
  • Pass render={<RouterLink />} to Brand or NavItem for router links
  • Header.SkipLink should be the first child

Installation

pnpm add @usefragments/ui

The npm package stays managed by your package manager. Import styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.

Anatomy

Import Header once, then compose its parts with dot notation.

  • Header.SkipLink
  • Header.Trigger
  • Header.Brand
  • Header.Nav
  • Header.NavItem
  • Header.NavMenu
  • Header.NavMenuItem
  • Header.Search
  • Header.Actions

Brand, nav with the current page marked, and one action.

import { Button } from '@usefragments/ui';
import { Header } from '@usefragments/ui';

<Header>
  <Header.SkipLink />
  <Header.Brand href="/">Fragments</Header.Brand>
  <Header.Nav>
    <Header.NavItem href="/overview" active>Overview</Header.NavItem>
    <Header.NavItem href="/findings">Findings</Header.NavItem>
    <Header.NavItem href="/settings">Settings</Header.NavItem>
  </Header.Nav>
  <Header.Actions>
    <Button variant="soft">Sign in</Button>
  </Header.Actions>
</Header>

Examples

With Dropdown Nav

Header.NavMenu groups related pages behind one trigger.

Loading With Dropdown Nav preview…

import { Header } from '@usefragments/ui';

<Header>
  <Header.Brand href="/">Fragments</Header.Brand>
  <Header.Nav>
    <Header.NavItem href="/overview">Overview</Header.NavItem>

Search between brand and actions; the Input owns its fill.

Loading With Search preview…

import { Button } from '@usefragments/ui';
import { Header } from '@usefragments/ui';
import { Input } from '@usefragments/ui';

<Header>
  <Header.Brand href="/">Fragments</Header.Brand>

Sticky Marketing Bar

Sticks to the top and draws the hairline once the page scrolls.

Loading Sticky Marketing Bar preview…

import { Button } from '@usefragments/ui';
import { Header } from '@usefragments/ui';

<Header position="sticky" elevatedOnScroll>
  <Header.SkipLink />
  <Header.Brand render={<a href="/" />}>Fragments</Header.Brand>

Mobile Navigation

Without a sidebar, the trigger opens a Drawer of Sidebar.Item rows.

Loading Mobile Navigation preview…

import { Drawer } from '@usefragments/ui';
import { Header } from '@usefragments/ui';
import { Sidebar } from '@usefragments/ui';

const [open, setOpen] = React.useState(false);

API reference

Component props
Prop
Type
Default
Description
Actions.childrenRequiredReact.ReactNodeNot set—
Brand.childrenRequiredReact.ReactNodeNot set—
Brand.hrefstring | undefinedNot setRenders a link.
Brand.renderuseRender.RenderProp<Record<string, unknown>> | undefinedNot setReplace the rendered element, e.g. a router link: `render={<RouterLink to="/" />}`. The look and props move onto it.
childrenRequiredReact.ReactNodeNot setHeader content: Header.Brand, Header.Nav, Header.Search, Header.Actions, Header.Trigger, Header.SkipLink
elevatedOnScrollboolean | HeaderElevatedOnScrollOptions | undefinedfalseDraw the bottom hairline once the page scrolls (no shadow). Object form accepts { threshold?: number }, default 16.
Nav.aria-labelstring | undefinedNot setAccessible label for the navigation landmark.
Nav.childrenRequiredReact.ReactNodeNot set—
NavItem.activeboolean | undefinedNot setThe current page: wash and ring, `aria-current="page"`.
NavItem.childrenRequiredReact.ReactNodeNot set—
NavItem.disabledboolean | undefinedNot setThe item cannot be used.
NavItem.hrefstring | undefinedNot setRenders a link.
NavItem.onClickReact.MouseEventHandler<HTMLElement> | undefinedNot setClick handler.
NavItem.relstring | undefinedNot setAnchor rel, when `href` renders an anchor.
NavItem.renderuseRender.RenderProp<Record<string, unknown>> | undefinedNot setReplace the rendered element, e.g. a router link.
NavItem.targetReact.HTMLAttributeAnchorTarget | undefinedNot setAnchor target, when `href` renders an anchor.
NavMenu.activeboolean | undefinedNot setThe current page is one of this group's items.
NavMenu.childrenRequiredReact.ReactNodeNot set—
NavMenu.disabledboolean | undefinedNot setThe group cannot be opened.
NavMenu.labelRequiredReact.ReactNodeNot setThe trigger label.
NavMenuItem.activeboolean | undefinedNot setThe current page.
NavMenuItem.childrenRequiredReact.ReactNodeNot set—
NavMenuItem.disabledboolean | undefinedNot setThe item cannot be chosen.
NavMenuItem.hrefstring | undefinedNot setRenders a link.
NavMenuItem.renderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>> | undefinedNot setReplace the rendered element, e.g. a router link.
position"static" | "sticky" | undefinedstaticstickystatic`sticky` keeps the bar at the top of its scroll container
Search.childrenRequiredReact.ReactNodeNot set—
Search.expandableboolean | undefinedNot setKeep the search visible when the bar is narrower than md.
SkipLink.childrenReact.ReactNodeNot set—
SkipLink.hrefstring | undefinedNot setThe id of the main region.
Trigger.aria-labelstring | undefinedNot setAccessible label.
Trigger.childrenReact.ReactNodeNot setCustom glyph.

Accessibility

  • Renders a banner landmark (<header>)
  • Header.SkipLink jumps keyboard users to #main-content
  • Header.Nav is a labelled navigation landmark (default "Main navigation")
  • The current item carries aria-current="page"; a disabled item is aria-disabled and leaves the tab order
  • Header.Trigger has an accessible label and aria-expanded; inside a sidebar it also sets aria-controls
  • Header.NavMenu is a Base UI menu: click or Enter opens it, arrow keys move, Escape closes
  • Nav items keep a 32px track and a hit area that grows to 44px under a coarse pointer
  • AppShellparentHeader usually sits inside AppShell.Header
  • SidebarsiblingHeader.Trigger opens the sidebar's mobile panel and brings back a hidden rail
  • DrawersiblingWithout a sidebar, Header.Trigger opens a Drawer of Sidebar.Item rows
  • ThemechildThe colour-mode control (a ToggleGroup wired to useTheme) commonly sits in Header.Actions

Next steps