Skip to main content

navigation menu

A collection of links for navigating websites.

Philosophy

Navigation menus serve a different purpose than dropdown menus - they're for wayfinding, not actions. The distinction matters for accessibility: navigation menus use <nav> and link semantics, while dropdown menus use role="menu" and button semantics. We expose viewport and indicator sub-components for advanced hover/focus animations.

Installation


npx @gentleduck/cli add navigation-menu

npx @gentleduck/cli add navigation-menu

Usage

import {
  NavigationMenu,
  NavigationMenuContent,
  NavigationMenuIndicator,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from "@/components/ui/navigation-menu"
import {
  NavigationMenu,
  NavigationMenuContent,
  NavigationMenuIndicator,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuTrigger,
  NavigationMenuViewport,
} from "@/components/ui/navigation-menu"
<NavigationMenu>
  <NavigationMenuList>
    <NavigationMenuItem>
      <NavigationMenuTrigger>Item One</NavigationMenuTrigger>
      <NavigationMenuContent>
        <NavigationMenuLink>Link</NavigationMenuLink>
      </NavigationMenuContent>
    </NavigationMenuItem>
  </NavigationMenuList>
</NavigationMenu>
<NavigationMenu>
  <NavigationMenuList>
    <NavigationMenuItem>
      <NavigationMenuTrigger>Item One</NavigationMenuTrigger>
      <NavigationMenuContent>
        <NavigationMenuLink>Link</NavigationMenuLink>
      </NavigationMenuContent>
    </NavigationMenuItem>
  </NavigationMenuList>
</NavigationMenu>

Component Composition

Loading diagram...

You can use the asChild prop to make another component look like a navigation menu trigger. Here's an example of a link that looks like a navigation menu trigger.

components/example-navigation-menu.tsx
import Link from "next/link"
 
export function NavigationMenuDemo() {
  return (
    <NavigationMenuItem>
      <NavigationMenuLink asChild>
        <Link href="/www">Documentation</Link>
      </NavigationMenuLink>
    </NavigationMenuItem>
  )
}
components/example-navigation-menu.tsx
import Link from "next/link"
 
export function NavigationMenuDemo() {
  return (
    <NavigationMenuItem>
      <NavigationMenuLink asChild>
        <Link href="/www">Documentation</Link>
      </NavigationMenuLink>
    </NavigationMenuItem>
  )
}

RTL Support

Set dir="rtl" on NavigationMenu for a local override, or set DirectionProvider once at app/root level for global direction.

Motion

Use MotionNavigationMenu for a spring-powered entrance animation with blur powered by motion.

API Reference

Root container that wraps the navigation menu and optionally renders the viewport.

PropTypeDefaultDescription
valuestring-Controlled value of the active menu item
defaultValuestring-Default active value for uncontrolled usage
onValueChange(value: string) => void-Callback when the active value changes
viewportbooleantrueWhether to render the NavigationMenuViewport automatically
dir'ltr' | 'rtl'-Text direction. Resolved by primitives useDirection (dir prop -> DirectionProvider -> 'ltr') and inherited by descendants.
orientation'horizontal' | 'vertical''horizontal'The orientation of the menu
delayDurationnumber200Duration in ms from when the pointer enters a trigger until the content opens
skipDelayDurationnumber300Duration in ms a user has to enter another trigger without incurring a delay again
classNamestring-Additional CSS classes for the root element
childrenReact.ReactNode-Navigation menu list and other elements
...propsReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>-Additional props inherited from NavigationMenu.Root.
PropTypeDefaultDescription
classNamestring--Additional CSS classes for the list element
...propsReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>-Additional props inherited from NavigationMenu.List.
PropTypeDefaultDescription
classNamestring--Additional CSS classes for the menu item
...propsReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Item>-Additional props inherited from NavigationMenu.Item.
PropTypeDefaultDescription
classNamestring--Additional CSS classes for the trigger
childrenReact.ReactNode--Trigger label content. A chevron icon is appended automatically
...propsReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>-Additional props inherited from NavigationMenu.Trigger.
PropTypeDefaultDescription
classNamestring--Additional CSS classes for the content panel
...propsReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>-Additional props inherited from NavigationMenu.Content.
PropTypeDefaultDescription
classNamestring--Additional CSS classes for the link
...propsReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Link>-Additional props inherited from NavigationMenu.Link.
PropTypeDefaultDescription
classNamestring--Additional CSS classes for the viewport
...propsReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>-Additional props inherited from NavigationMenu.Viewport.
PropTypeDefaultDescription
classNamestring--Additional CSS classes for the indicator
...propsReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>-Additional props inherited from NavigationMenu.Indicator.

A cva variant function that returns the default trigger styling classes. Use it to style non-trigger elements (e.g. plain links) to match the trigger appearance.

import { navigationMenuTriggerStyle } from "@/components/ui/navigation-menu"
 
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
  Documentation
</NavigationMenuLink>
import { navigationMenuTriggerStyle } from "@/components/ui/navigation-menu"
 
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
  Documentation
</NavigationMenuLink>

MotionNavigationMenu

Same props as NavigationMenu. Adds spring scaleIn+blur entrance animation via motion. Requires the motion package.