Navigation Menu
StableTop-level site navigation with rich, animated panels — for marketing sites and documentation where each section needs more than a single link.
Installation
$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/navigation-menu.jsonUsage
import Link from "next/link"
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu"<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Products</NavigationMenuTrigger>
<NavigationMenuContent>
<NavigationMenuLink render={<Link href="/analytics" />}>
Analytics
</NavigationMenuLink>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink
render={<Link href="/pricing" />}
className={navigationMenuTriggerStyle()}
>
Pricing
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>All panels share a single popup. When people move from one trigger to the next, the popup morphs to the new panel's size and the content slides in from the direction of travel — a strong spatial cue that they're browsing siblings, not opening something new.
Examples
Site navigation
Mix triggers that open panels with plain links styled by navigationMenuTriggerStyle(), so every item in the bar looks and behaves consistently.
Links with icons
A two-column list of destinations, each with an icon and a one-line description. Descriptions do the heavy lifting: they let people choose without clicking through.
Featured content
Reserve a panel's side column for one timely item — a launch, a guide, an event. One feature per panel; two features compete.
Links only
With no panels, the menu is a styled list of links with roving focus. Mark the current section with active — it sets aria-current="page" and the active style.
Guidelines
When to use
- For the primary navigation of marketing sites and documentation with a handful of top-level sections.
- When a section needs orientation — descriptions, grouping or a featured item — before people choose where to go.
When not to use
- For app navigation with many destinations or deep hierarchies — use a Sidebar.
- For commands and actions — use a Dropdown Menu or Menubar. Navigation menus contain links only.
- On small screens — below
md, collapse the navigation into a Sheet with a simple list.
Panel content
Keep five to seven top-level items. Every link in a panel gets a short title and, ideally, a one-line description in sentence case — punctuated the same way across the panel. Group long panels into columns of related links, and don't hide anything important only inside a panel — the destination should also be reachable from the page itself or the footer.
Hover and click
Panels open on hover after a short delay (50ms) and on click. The popup and trigger are joined by an invisible bridge, so the pointer can travel diagonally into a panel without closing it. Never put a destination on the trigger itself — a trigger only opens its panel; the section's overview page belongs inside the panel as its first link.
Accessibility
Navigation Menu renders a <nav> with a list of items. Triggers are buttons with aria-expanded; panels are disclosed content, not menus — links inside are reached with Tab, just like on the page.
| Key | Behavior |
|---|---|
Tab | Moves through triggers and links, and into an open panel's links. |
←→ | Moves focus between top-level triggers and links. |
EnterSpace | Opens or closes the focused trigger's panel; follows the focused link. |
↓ | On a trigger, opens its panel and moves focus into it. |
Esc | Closes the panel and returns focus to its trigger. |
- Current page. Pass
activeto the link for the current page or section; it's exposed asaria-current="page". - Label multiple navs. If a page has more than one
<nav>, give each anaria-label(Main, Footer) so screen reader users can tell them apart.
API reference
NavigationMenu
The root <nav>. Accepts every prop of the Base UI NavigationMenu.Root.
NavigationMenuItem
NavigationMenuTrigger
Opens its item's panel. Renders a chevron that turns while open. Accepts disabled.
NavigationMenuContent
The panel for an item. Size it with a width on its first child; the popup animates between panel sizes.
NavigationMenuLink
navigationMenuTriggerStyle
A class generator that makes a plain NavigationMenuLink look exactly like a trigger. Accepts { className } to extend it.