Siteplane UI

Header Navigation

Pro

Lay out a site header with logo, menus, search and account.

Markdown
Pro

This example installs with a Siteplane UI Pro license key.

Get a license on the Pro page.

pnpm dlx shadcn@4.18.0 add @siteplane-pro/header-navigation-demo

This Pattern is part of Siteplane UI Pro, and its source comes with a Pro license. Its previews are free to view and try.

Installation

pnpm dlx shadcn@4.18.0 add @siteplane-pro/header-navigation
Pro

Installs with a Siteplane UI Pro license key. Complete the one-time Pro setup first.

Get a license on the Pro page.

Usage

import { HeaderNavigation } from "@/siteplane/components/header-navigation";

<HeaderNavigation
  brand={<a href="#home">Workspace</a>}
  items={[
    { current: true, href: "#home", label: "Home" },
    {
      groups: [
        { label: "Learn", links: [{ href: "#guides", label: "Guides" }] },
      ],
      label: "Resources",
    },
  ]}
/>;

Composition

HeaderNavigation
├── brand
├── NavigationMenu (header from 64rem wide)
│   ├── link → NavigationMenuLink
│   └── dropdown → NavigationMenuTrigger and NavigationMenuContent
│       └── groups of links with descriptions and badges
├── search
├── actions
└── account → HeaderAccountMenu

Header below 64rem: brand and a menu button → fullscreen Sidebar
├── actions, search and links (a dropdown opens a second level)
└── mobileFooter, or account

Every entry in items is a link or a dropdown. A link takes label, href, and optionally current, which sets aria-current="page", and a badge. A dropdown takes a label and groups of links. With more than one group the panel shows two columns; a link inside a dropdown can also carry a description. The desktop row is a Navigation Menu, so the panels share one popup that resizes and cross-fades when you move between them. The first example shows two links, two dropdowns and the account menu.

Pass search for a field before the actions. It takes a 12 rem slot in the row and sits at the top of the mobile menu.

Pro

This example installs with a Siteplane UI Pro license key.

Get a license on the Pro page.

pnpm dlx shadcn@4.18.0 add @siteplane-pro/header-navigation-search-example

Actions

Pass actions for buttons next to the account menu, such as an upgrade button or a notification link. IconButton shows a count and carries its meaning in the label. In the mobile menu the actions form the first row.

Pro

This example installs with a Siteplane UI Pro license key.

Get a license on the Pro page.

pnpm dlx shadcn@4.18.0 add @siteplane-pro/header-navigation-actions-example

Account menu

HeaderAccountMenu renders the account trigger and its menu. Items with children open a submenu, accounts adds an account switcher, and footer takes any menu content, such as a sign-out item. Each account row leads with its avatar and ends with the check of the current account, like the workspace switcher of Sidebar; the avatar stays out of the row's accessible name, which the account's name gives. Set card for the full-width trigger that suits the mobile menu, and pass it as mobileFooter.

Pro

This example installs with a Siteplane UI Pro license key.

Get a license on the Pro page.

pnpm dlx shadcn@4.18.0 add @siteplane-pro/header-navigation-account-example

Mobile navigation

In a header narrower than 64rem (1024 px) the header shows the brand and a menu button. The button opens a fullscreen sidebar with the actions, the search field and the links; a dropdown opens a second level with a Back link. mobileFooter replaces account at the bottom of that menu. The switch follows the width of the header, not of the window, so a header in a narrow column shows the menu button as on a phone, and so does a preview on this page that is narrower than 64rem.

API reference

Component properties
PropTypeDefaultDescription
HeaderNavigation.brandReactNoderequiredLogo or name at the start of the row and in the mobile menu.
HeaderNavigation.itemsreadonly HeaderNavigationItem[]requiredLinks and dropdowns, in order.
HeaderNavigation.searchReactNodeunsetSearch field. 12 rem wide in the row, full width in the mobile menu.
HeaderNavigation.actionsReactNodeunsetButtons before the account; the first row of the mobile menu.
HeaderNavigation.accountReactNodeunsetAccount trigger at the end of the row. It is also the mobile footer unless mobileFooter is set.
HeaderNavigation.mobileFooterReactNodeaccountContent at the bottom of the mobile menu.
HeaderNavigation.navigationLabelstringMain navigationAccessible name of the navigation landmark.
HeaderNavigation.menuLabelstringNavigationAccessible name of the mobile menu button and of the menu it opens.
HeaderNavigation.closeLabel / backLabelstringClose navigation / BackAccessible name of the mobile menu's close buttons, and the text of the Back button on its second level.
HeaderNavigationLink{ label: string; href: string; current?: boolean; badge?: ReactNode; description?: string }—A destination. description shows inside dropdown panels and the mobile second level.
HeaderNavigationDropdown{ label: string; badge?: ReactNode; groups: readonly HeaderNavigationLinkGroup[] }—A trigger that opens a panel. A group is { label?: string; links: readonly HeaderNavigationLink[] }.
HeaderAccountMenu.labelstringrequiredAccessible name of the trigger and the name in the menu header.
HeaderAccountMenu.avatar{ src?: string; initials: string }unsetRound avatar trigger and a header in the menu. Without it the trigger is an outline button with the label.
HeaderAccountMenu.detailstringunsetSecond line under the name, such as an email address.
HeaderAccountMenu.cardbooleanfalseFull-width trigger with name and detail, for the mobile menu.
HeaderAccountMenu.items / secondaryItemsreadonly HeaderAccountMenuItem[]required / []Menu items: { label, href?, onClick?, icon?, shortcut?, children? }. children makes a submenu of { label, href?, onClick?, icon? }. Lead every item with an icon. secondaryItems follow the dark mode switch after a divider.
HeaderAccountMenu.footerReactNodeunsetContent after a last divider, such as a sign-out MenuItem.
HeaderAccountMenu.accountsreadonly { id: string; name: string; src?: string; initials?: string }[]unsetAccount switcher as a radio group.
HeaderAccountMenu.accountId / onAccountChangestring / (id: string) => voidunsetSelected account and its change handler.
HeaderAccountMenu.accountsLabel / addAccountLabelstringSwitch account / Add accountLabels of the switcher group and of the add item.
HeaderAccountMenu.onAddAccount() => voidunsetShows the add item and runs when it is chosen.
HeaderAccountMenu.darkMode / onDarkModeChange / darkModeLabelboolean / (dark: boolean) => void / stringunset / unset / Dark modeShows a switch in the menu. It only reports the change; your application applies the theme.

HeaderNavigationProps extends native header props, so className and id reach the header element. The row spans the available width up to max-w-7xl and ends in a divider. Exported types: HeaderNavigationItem, HeaderNavigationLink, HeaderNavigationLinkGroup, HeaderNavigationDropdown, HeaderNavigationProps, HeaderAccountMenuItem and HeaderAccountMenuProps.

Usage notes

The desktop row does not wrap. Links, search, actions and the account menu share one line from 1024 px on, so choose as many as fit there. Five links with two dropdowns, a search field, three actions and an account menu need about 1000 px, more than the preview on this page offers, so each example shows part of that set. The header is not sticky and does not route: links are plain anchors, so use real destinations and handle client-side navigation in your application. The examples use fragment destinations to keep the preview local.

Mark the current page with current so it is announced. Its link keeps a persistent fill and the full foreground, on the desktop row and in the mobile menu. Describe icon-only actions in their label. Panels fade and move a few pixels as they open, and reduced motion removes the movement. The header paints the page background; place it at the top of the page, above the content.