Components
Navigation menu

Navigation Menu

A collection of links and menus for website navigation.

Loading...

Anatomy

<NavigationMenu.Root>
  <NavigationMenu.List>
    <NavigationMenu.Item>
      <NavigationMenu.Trigger />
      <NavigationMenu.Content>
        <NavigationMenu.Link />
      </NavigationMenu.Content>
    </NavigationMenu.Item>
    <NavigationMenu.Indicator>
      <NavigationMenu.Arrow />
    </NavigationMenu.Indicator>
  </NavigationMenu.List>
  <NavigationMenu.ViewportPositioner>
    <NavigationMenu.Viewport />
  </NavigationMenu.ViewportPositioner>
</NavigationMenu.Root>

Examples

Viewport

Render NavigationMenu.Viewport to share one animated panel across menu items. The viewport resizes as you move between triggers.

Pass the current prop to the link that represents the page the user is on. It renders aria-current="page" for assistive technology and a data-current attribute for styling.

Vertical

Set orientation="vertical" on the root to build sidebar-style navigation. Panels open to the side, and the keyboard model adapts: ArrowUp and ArrowDown move between triggers, ArrowRight enters the open panel.

Controlled

Use the value and onValueChange props to control the active menu item.

Root Provider

An alternative way to control the navigation menu is to use the RootProvider component and the useNavigationMenu hook. This way you can access the state and methods from outside the component.

If you're using the RootProvider component, you don't need to use the Root component.

Context

Access the navigation menu's state with NavigationMenu.Context or the useNavigationMenuContext hook:

Guides

Use the asChild prop to render NavigationMenu.Link as your framework's link component for client-side routing.

import { Link as RouterLink } from 'react-router-dom'
import { NavigationMenu } from '@ark-ui/<framework>/navigation-menu'

export const MenuLink = (props: NavigationMenu.LinkProps) => {
  return (
    <NavigationMenu.Link {...props} asChild>
      <RouterLink to={props.href ?? '#'}>{props.children}</RouterLink>
    </NavigationMenu.Link>
  )
}

Viewport size

The following CSS variables are exposed on NavigationMenu.Root and NavigationMenu.Viewport:

/* size and position of the active trigger */
--trigger-width: <pixel-value>;
--trigger-height: <pixel-value>;
--trigger-x: <pixel-value>;
--trigger-y: <pixel-value>;

/* size and position of the active content */
--viewport-width: <pixel-value>;
--viewport-height: <pixel-value>;
--viewport-x: <pixel-value>;
--viewport-y: <pixel-value>;

Use --viewport-width and --viewport-height to animate the shared panel as the active item changes:

[data-scope='navigation-menu'][data-part='viewport'] {
  width: var(--viewport-width);
  height: var(--viewport-height);
  transition:
    width 250ms ease,
    height 250ms ease;
}

Large menus

When menu content is taller than the viewport, constrain the panel and scroll the content:

[data-scope='navigation-menu'][data-part='viewport'] {
  max-height: min(var(--viewport-height), 70vh);
}

[data-scope='navigation-menu'][data-part='content'] {
  max-height: 70vh;
  overflow-y: auto;
}

API Reference

Props

Root

Renders a <> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
closeDelay300
number

The delay before the menu closes

defaultValue
string

The default value of the navigation menu. Use when you don't want to control the value of the menu.

disableClickTrigger
boolean

Whether to disable the click trigger

disableHoverTrigger
boolean

Whether to disable the hover trigger

disablePointerLeaveClose
boolean

Whether to disable the pointer leave close

hideMode'display-none'
HideMode

How to hide content when mounted but not present. - `'display-none'`: HTML `hidden` attribute. Effects stay alive. - `'activity'`: React 19 `<Activity mode="hidden">`. Effects pause. Requires React 19+.

id
string

The unique identifier of the machine.

ids
Partial<{ root: string list: string item: string trigger: (value: string) => string content: (value: string) => string viewport: string }>

The ids of the elements in the machine.

lazyMountfalse
boolean

Whether to enable lazy mounting

onValueChange
(details: ValueChangeDetails) => void

Function called when the value of the menu changes

openDelay200
number

The delay before the menu opens

orientation'horizontal'
'horizontal' | 'vertical'

The orientation of the element.

translations
IntlTranslations

Specifies the localized strings that identifies the accessibility elements and their states

unmountOnExitfalse
boolean

Whether to unmount on exit.

value
string

The controlled value of the navigation menu

AttributeDescription
[data-scope]navigation-menu
[data-part]root
[data-orientation]The orientation of the navigation-menu
CSS VariableDescription
--trigger-widthThe width of the Root
--trigger-heightThe height of the Root
--trigger-xThe trigger x value for the Root
--trigger-yThe trigger y value for the Root
--viewport-widthThe width of the Root
--viewport-heightThe height of the Root
--viewport-xThe viewport x value for the Root
--viewport-yThe viewport y value for the Root

Arrow

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]navigation-menu
[data-part]arrow
[data-orientation]The orientation of the arrow

Content

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
value
string

The value of the item this content belongs to

AttributeDescription
[data-scope]navigation-menu
[data-part]content
[data-state]"open" | "closed"
[data-orientation]The orientation of the content
[data-value]The value of the item
CSS VariableDescription
--layer-indexThe index of the dismissable in the layer stack
--nested-layer-countThe number of nested navigation-menus

Indicator

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]navigation-menu
[data-part]indicator
[data-state]"open" | "closed"
[data-orientation]The orientation of the indicator

ItemIndicator

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]navigation-menu
[data-part]item-indicator
[data-state]"open" | "closed"
[data-orientation]The orientation of the item
[data-value]The value of the item

Item

Renders a <div> element.

PropDefaultType
value
string

The value of the item

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
disabled
boolean

Whether the item is disabled

AttributeDescription
[data-scope]navigation-menu
[data-part]item
[data-value]The value of the item
[data-state]"open" | "closed"
[data-orientation]The orientation of the item
[data-disabled]Present when disabled

Link

Renders a <a> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
closeOnClicktrue
boolean

Whether to close the navigation menu when the link is clicked.

current
boolean

Whether the link is the current link

onSelect
(event: CustomEvent<any>) => void

Function called when the link is selected

value
string

The value of the item this link belongs to

AttributeDescription
[data-scope]navigation-menu
[data-part]link
[data-value]The value of the item
[data-current]Present when current

List

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]navigation-menu
[data-part]list
[data-orientation]The orientation of the list

RootProvider

Renders a <> element.

PropDefaultType
value
UseNavigationMenuReturn

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
hideMode'display-none'
HideMode

How to hide content when mounted but not present. - `'display-none'`: HTML `hidden` attribute. Effects stay alive. - `'activity'`: React 19 `<Activity mode="hidden">`. Effects pause. Requires React 19+.

lazyMountfalse
boolean

Whether to enable lazy mounting

unmountOnExitfalse
boolean

Whether to unmount on exit.

Trigger

Renders a <button> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
disabled
boolean

Whether the item is disabled

AttributeDescription
[data-scope]navigation-menu
[data-part]trigger
[data-trigger-proxy-id]
[data-value]The value of the item
[data-state]"open" | "closed"
[data-disabled]Present when disabled

ViewportPositioner

Renders a <div> element.

PropDefaultType
align
'center' | 'start' | 'end'

Placement of the viewport for css variables `(--viewport-x, --viewport-y)`.

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]navigation-menu
[data-part]viewport-positioner
[data-orientation]The orientation of the viewportpositioner
[data-align]

Viewport

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]navigation-menu
[data-part]viewport
[data-state]"open" | "closed"
[data-orientation]The orientation of the viewport
[data-align]
CSS VariableDescription
--viewport-widthThe width of the Viewport
--viewport-heightThe height of the Viewport
--viewport-xThe viewport x value for the Viewport
--viewport-yThe viewport y value for the Viewport

Context

API

PropertyType
value
string | null

The current value of the menu

setValue
(value: string) => void

Sets the value of the menu

open
boolean

Whether the menu is open

isViewportRendered
boolean

Whether the viewport is rendered

getViewportNode
() => HTMLElement | null

Gets the viewport node element

orientation
Orientation

The orientation of the menu

reposition
VoidFunction

Function to reposition the viewport

Accessibility

Complies with the Navigation Menubar WAI-ARIA design pattern.

Keyboard Support

KeyDescription
ArrowDown
When focus is on trigger (vertical orientation), moves focus to the next trigger.
ArrowUp
When focus is on trigger (vertical orientation), moves focus to the previous trigger.
ArrowRight
When focus is on trigger (horizontal orientation), moves focus to the next trigger.
When focus is on content, moves focus to the next link.
ArrowLeft
When focus is on trigger (horizontal orientation), moves focus to the previous trigger.
When focus is on content, moves focus to the previous link.
Home
When focus is on trigger, moves focus to the first trigger.
When focus is on content, moves focus to the first link.
End
When focus is on trigger, moves focus to the last trigger.
When focus is on content, moves focus to the last link.