Components
HeaderNav
The desktop link row: a simple flex container of HeaderNavItems for the Header's nav slot. Give an item children and it becomes a dropdown menu that opens on hover or click.
Overview
HeaderNav itself is deliberately small — a flex <nav> that lines up HeaderNavItems, with className and an aria-label override for the landmark (defaults to “Main”) alongside children. Pass it to the Header’s nav prop; the Header renders that slot only from the md breakpoint up, so on phones the links disappear and the mobileMenu panel takes over. Without children, an item renders as a plain link (href) or a button.
import { AppShell, Header, HeaderNav, HeaderNavItem, Content } from "appshell-react";
export default function App() {
return (
<AppShell safeArea>
<Header
behavior="fixed"
logo={<span className="font-bold">Nimbus</span>}
nav={
<HeaderNav>
{/* children make this item a dropdown */}
<HeaderNavItem label="Products" active>
<a
className="block rounded-md px-3 py-2 text-sm hover:bg-accent"
href="/analytics"
>
Analytics
</a>
<a
className="block rounded-md px-3 py-2 text-sm hover:bg-accent"
href="/automation"
>
Automation
</a>
</HeaderNavItem>
<HeaderNavItem label="Pricing" href="/pricing" />
<HeaderNavItem label="Docs" href="/docs" />
</HeaderNav>
}
mobileMenu={
<nav className="flex flex-col gap-1">
<a className="rounded-md px-3 py-2 hover:bg-accent" href="/products">
Products
</a>
<a className="rounded-md px-3 py-2 hover:bg-accent" href="/pricing">
Pricing
</a>
<a className="rounded-md px-3 py-2 hover:bg-accent" href="/docs">
Docs
</a>
</nav>
}
/>
<Content className="p-4">{/* landing content */}</Content>
</AppShell>
);
}Dropdowns
Passing children to a HeaderNavItem turns it into a dropdown trigger: a button with a rotating chevron, aria-haspopup, and aria-expanded. The panel opens on hover (with a 150ms grace period when the pointer leaves, so you can move into the panel) or on click as a toggle, and closes on Escape or a click outside. It renders absolutely below the trigger as a role="menu" panel styled with the popover tokens (bg-popover, border-border) — the content inside is entirely yours, typically a column of links.
animate-in fade-in zoom-in-95 utilities from tw-animate-css — install and import that plugin (see Installation) or the panel simply appears without the fade. And keyboard support inside the panel is minimal: Escape closes it, but there is no arrow-key menu navigation — items are plain focusable links.Theme awareness
Items read the active Header theme through useHeaderTheme() and adapt automatically: accent-token hover/active styles on "light", translucent primary-foreground styles on "primary" and "dark" headers. (On theme="none" items fall back to the light styles — override with className if you are bringing your own header skin.) See Theming for the token details.