Skip to content

Menubar

A persistent row of menus, such as File, Edit and View, that gives desktop-class applications a complete, discoverable set of commands.

SourceBase UIRegistry
import {
  Menubar,
  MenubarCheckboxItem,
  MenubarContent,
  MenubarGroup,
  MenubarItem,
  MenubarMenu,
  MenubarRadioGroup,
  MenubarRadioItem,
  MenubarSeparator,
  MenubarShortcut,
  MenubarSub,
  MenubarSubContent,
  MenubarSubTrigger,
  MenubarTrigger,
} from "@/components/ui/menubar"

export default function MenubarDemo() {
  return (
    <Menubar>
      <MenubarMenu>
        <MenubarTrigger>File</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarItem>
              New tab <MenubarShortcut>⌘T</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              New window <MenubarShortcut>⌘N</MenubarShortcut>
            </MenubarItem>
            <MenubarItem disabled>New incognito window</MenubarItem>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarSub>
              <MenubarSubTrigger>Share</MenubarSubTrigger>
              <MenubarSubContent>
                <MenubarGroup>
                  <MenubarItem>Email link</MenubarItem>
                  <MenubarItem>Messages</MenubarItem>
                  <MenubarItem>Notes</MenubarItem>
                </MenubarGroup>
              </MenubarSubContent>
            </MenubarSub>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarItem>
              Print… <MenubarShortcut>⌘P</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
      <MenubarMenu>
        <MenubarTrigger>Edit</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarItem>
              Undo <MenubarShortcut>⌘Z</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              Redo <MenubarShortcut>⇧⌘Z</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarItem>
              Cut <MenubarShortcut>⌘X</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              Copy <MenubarShortcut>⌘C</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              Paste <MenubarShortcut>⌘V</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
      <MenubarMenu>
        <MenubarTrigger>View</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarCheckboxItem defaultChecked>
              Show bookmarks bar
            </MenubarCheckboxItem>
            <MenubarCheckboxItem>Show full URLs</MenubarCheckboxItem>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarItem inset>
              Reload <MenubarShortcut>⌘R</MenubarShortcut>
            </MenubarItem>
            <MenubarItem inset>
              Toggle full screen <MenubarShortcut>⌃⌘F</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
      <MenubarMenu>
        <MenubarTrigger>Profiles</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarRadioGroup defaultValue="ada">
              <MenubarRadioItem value="ada">Ada</MenubarRadioItem>
              <MenubarRadioItem value="grace">Grace</MenubarRadioItem>
              <MenubarRadioItem value="alan">Alan</MenubarRadioItem>
            </MenubarRadioGroup>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarItem inset>Edit profiles…</MenubarItem>
            <MenubarItem inset>Add profile…</MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
    </Menubar>
  )
}

Installation

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/menubar.json

Usage

import {
  Menubar,
  MenubarContent,
  MenubarGroup,
  MenubarItem,
  MenubarMenu,
  MenubarShortcut,
  MenubarTrigger,
} from "@/components/ui/menubar"
<Menubar>
  <MenubarMenu>
    <MenubarTrigger>File</MenubarTrigger>
    <MenubarContent>
      <MenubarGroup>
        <MenubarItem>
          New tab <MenubarShortcut>⌘T</MenubarShortcut>
        </MenubarItem>
        <MenubarItem>New window</MenubarItem>
      </MenubarGroup>
    </MenubarContent>
  </MenubarMenu>
</Menubar>

Each MenubarMenu is a Dropdown Menu whose trigger lives in the bar, so every item type — checkbox, radio, submenu, destructive — is available with the same API. Once one menu is open, hovering or arrowing to a sibling trigger switches menus without another click.

Examples

Application menubar

A complete bar with shortcuts, a submenu, checkbox items in View and a radio group in Profiles.

import {
  Menubar,
  MenubarCheckboxItem,
  MenubarContent,
  MenubarGroup,
  MenubarItem,
  MenubarMenu,
  MenubarRadioGroup,
  MenubarRadioItem,
  MenubarSeparator,
  MenubarShortcut,
  MenubarSub,
  MenubarSubContent,
  MenubarSubTrigger,
  MenubarTrigger,
} from "@/components/ui/menubar"

export default function MenubarDemo() {
  return (
    <Menubar>
      <MenubarMenu>
        <MenubarTrigger>File</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarItem>
              New tab <MenubarShortcut>⌘T</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              New window <MenubarShortcut>⌘N</MenubarShortcut>
            </MenubarItem>
            <MenubarItem disabled>New incognito window</MenubarItem>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarSub>
              <MenubarSubTrigger>Share</MenubarSubTrigger>
              <MenubarSubContent>
                <MenubarGroup>
                  <MenubarItem>Email link</MenubarItem>
                  <MenubarItem>Messages</MenubarItem>
                  <MenubarItem>Notes</MenubarItem>
                </MenubarGroup>
              </MenubarSubContent>
            </MenubarSub>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarItem>
              Print… <MenubarShortcut>⌘P</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
      <MenubarMenu>
        <MenubarTrigger>Edit</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarItem>
              Undo <MenubarShortcut>⌘Z</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              Redo <MenubarShortcut>⇧⌘Z</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarItem>
              Cut <MenubarShortcut>⌘X</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              Copy <MenubarShortcut>⌘C</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              Paste <MenubarShortcut>⌘V</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
      <MenubarMenu>
        <MenubarTrigger>View</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarCheckboxItem defaultChecked>
              Show bookmarks bar
            </MenubarCheckboxItem>
            <MenubarCheckboxItem>Show full URLs</MenubarCheckboxItem>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarItem inset>
              Reload <MenubarShortcut>⌘R</MenubarShortcut>
            </MenubarItem>
            <MenubarItem inset>
              Toggle full screen <MenubarShortcut>⌃⌘F</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
      <MenubarMenu>
        <MenubarTrigger>Profiles</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarRadioGroup defaultValue="ada">
              <MenubarRadioItem value="ada">Ada</MenubarRadioItem>
              <MenubarRadioItem value="grace">Grace</MenubarRadioItem>
              <MenubarRadioItem value="alan">Alan</MenubarRadioItem>
            </MenubarRadioGroup>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarItem inset>Edit profiles…</MenubarItem>
            <MenubarItem inset>Add profile…</MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
    </Menubar>
  )
}

Editor menus

Labels group related commands inside a long menu; icons make formatting commands recognizable at a glance.

import {
  AlignCenterIcon,
  AlignLeftIcon,
  AlignRightIcon,
  BoldIcon,
  ItalicIcon,
  UnderlineIcon,
} from "lucide-react"

import {
  Menubar,
  MenubarContent,
  MenubarGroup,
  MenubarItem,
  MenubarLabel,
  MenubarMenu,
  MenubarRadioGroup,
  MenubarRadioItem,
  MenubarSeparator,
  MenubarShortcut,
  MenubarTrigger,
} from "@/components/ui/menubar"

export default function MenubarEditor() {
  return (
    <Menubar>
      <MenubarMenu>
        <MenubarTrigger>Format</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarLabel>Text</MenubarLabel>
            <MenubarItem>
              <BoldIcon />
              Bold
              <MenubarShortcut>⌘B</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              <ItalicIcon />
              Italic
              <MenubarShortcut>⌘I</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              <UnderlineIcon />
              Underline
              <MenubarShortcut>⌘U</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
          <MenubarSeparator />
          <MenubarGroup>
            <MenubarLabel>Alignment</MenubarLabel>
            <MenubarItem>
              <AlignLeftIcon />
              Left
              <MenubarShortcut>⇧⌘L</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              <AlignCenterIcon />
              Center
              <MenubarShortcut>⇧⌘E</MenubarShortcut>
            </MenubarItem>
            <MenubarItem>
              <AlignRightIcon />
              Right
              <MenubarShortcut>⇧⌘R</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
      <MenubarMenu>
        <MenubarTrigger>Layout</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarLabel>Page width</MenubarLabel>
            <MenubarRadioGroup defaultValue="comfortable">
              <MenubarRadioItem value="narrow">Narrow</MenubarRadioItem>
              <MenubarRadioItem value="comfortable">
                Comfortable
              </MenubarRadioItem>
              <MenubarRadioItem value="full">Full width</MenubarRadioItem>
            </MenubarRadioGroup>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
    </Menubar>
  )
}

Checkbox items

Toggle panels and chrome without closing the menu. Keep the state in your app so the same settings can be changed from other surfaces too.

Visible: Sidebar, Inspector

"use client"

import * as React from "react"

import {
  Menubar,
  MenubarCheckboxItem,
  MenubarContent,
  MenubarGroup,
  MenubarLabel,
  MenubarMenu,
  MenubarSeparator,
  MenubarTrigger,
} from "@/components/ui/menubar"

const panels = ["Sidebar", "Inspector", "Timeline", "Minimap"] as const

export default function MenubarCheckboxItems() {
  const [open, setOpen] = React.useState<Record<string, boolean>>({
    Sidebar: true,
    Inspector: true,
    Timeline: false,
    Minimap: false,
  })

  return (
    <div className="flex flex-col items-center gap-4">
      <Menubar>
        <MenubarMenu>
          <MenubarTrigger>View</MenubarTrigger>
          <MenubarContent>
            <MenubarGroup>
              <MenubarLabel>Panels</MenubarLabel>
              {panels.map((panel) => (
                <MenubarCheckboxItem
                  key={panel}
                  checked={open[panel]}
                  onCheckedChange={(checked) =>
                    setOpen((current) => ({ ...current, [panel]: checked }))
                  }
                >
                  {panel}
                </MenubarCheckboxItem>
              ))}
            </MenubarGroup>
            <MenubarSeparator />
            <MenubarGroup>
              <MenubarCheckboxItem
                checked={Object.values(open).every(Boolean)}
                onCheckedChange={(checked) =>
                  setOpen(Object.fromEntries(panels.map((p) => [p, checked])))
                }
              >
                Show all panels
              </MenubarCheckboxItem>
            </MenubarGroup>
          </MenubarContent>
        </MenubarMenu>
      </Menubar>
      <p className="text-sm text-muted-foreground">
        Visible: {panels.filter((p) => open[p]).join(", ") || "none"}
      </p>
    </div>
  )
}

Disabled items and menus

Disable items that don't apply to the current selection, such as Redo with nothing to redo. Disable a whole menu with disabled on MenubarMenu when its commands are unavailable, rather than hiding it — a stable bar is easier to learn.

import {
  Menubar,
  MenubarContent,
  MenubarGroup,
  MenubarItem,
  MenubarMenu,
  MenubarShortcut,
  MenubarTrigger,
} from "@/components/ui/menubar"

export default function MenubarDisabled() {
  return (
    <Menubar>
      <MenubarMenu>
        <MenubarTrigger>Edit</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarItem>
              Undo <MenubarShortcut>⌘Z</MenubarShortcut>
            </MenubarItem>
            <MenubarItem disabled>
              Redo <MenubarShortcut>⇧⌘Z</MenubarShortcut>
            </MenubarItem>
            <MenubarItem disabled>
              Paste <MenubarShortcut>⌘V</MenubarShortcut>
            </MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
      <MenubarMenu disabled>
        <MenubarTrigger>Plugins</MenubarTrigger>
        <MenubarContent>
          <MenubarGroup>
            <MenubarItem>Manage plugins…</MenubarItem>
          </MenubarGroup>
        </MenubarContent>
      </MenubarMenu>
    </Menubar>
  )
}

Guidelines

When to use

  • In document editors, design tools, IDE-like apps and dashboards with many commands, where people expect a desktop-style menu bar.
  • When commands need a permanent, browsable home in addition to shortcuts and toolbars.

When not to use

  • On content sites and simple apps — top-level navigation belongs in a Navigation Menu.
  • For a handful of actions — a toolbar of Buttons or a single Dropdown Menu is lighter.
  • On small screens — collapse the bar into a single menu or a Command palette below md.

Conventional order

People bring expectations from every desktop app they've used. Follow the conventional order — File, Edit, View, then app-specific menus, then Window and Help — and keep labels in the bar to a single word. Inside menus, follow the Dropdown Menu content rules.

Every item needs a second path

Menubars are for discovery and teach shortcuts. Show the shortcut for every command that has one, and make sure frequent commands are also reachable from a toolbar, context menu or the Command palette.

Accessibility

Menubar implements the WAI-ARIA menubar pattern: the bar is a single tab stop with roving focus between its triggers.

KeyBehavior
Tab
Moves focus into the bar (to the last focused trigger) and out of it.
←→
Moves between triggers. With a menu open, opens the neighboring menu instead.
EnterSpace↓
Opens the focused menu and focuses its first item.
↓↑
Inside a menu, moves between items.
→
On a submenu trigger, opens the submenu.
A–Z
Typeahead to the next item starting with the typed characters.
Esc
Closes the menu and returns focus to its trigger in the bar.

API reference

The bar. Accepts every prop of the Base UI Menubar.

PropTypeDefault
orientation

Direction of the bar and of arrow-key navigation between triggers.

"horizontal" | "vertical""horizontal"
loopFocus

Whether focus wraps from the last trigger to the first.

booleantrue
modal

Whether an open menu locks page scroll and blocks pointer interaction with the rest of the page.

booleantrue
disabled

Disables every menu in the bar.

booleanfalse

A single menu in the bar — a DropdownMenu root. Accepts open, defaultOpen, onOpenChange and disabled.

The bar-level button that opens its menu. Highlights while its menu is open and dims when disabled.

PropTypeDefault
align

Alignment against the trigger.

"start" | "center" | "end""start"
alignOffset

Aligns the menu's first item text with the trigger label.

number-2
sideOffset

Gap between bar and menu, in px.

number8

Other parts

MenubarItem, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSub, MenubarSubTrigger, MenubarSubContent, MenubarLabel, MenubarSeparator, MenubarShortcut, MenubarGroup and MenubarPortal are the Dropdown Menu parts with menubar data slots, so they share every prop.