Component guideEditable source

Sidebar

Application navigation with desktop collapse and a mobile sheet.

Original component docs
On this page5 sectionsBack to top

Use SidebarProvider around both sidebar and main content. Sidebar is an application layout, not just a list of links. Installation includes the mobile detection hook and the component source.

Live preview
Loading preview...

#Installation

Complete the base setup. The CLI installs both files and dependencies. For manual installation:

npx shadcn@latest add https://neobrutal-ui.andongmin.com/r/sidebar.json

The default keyboard toggle is Ctrl+B or Command+B. Check for conflicts with your application shortcuts.

The complete live preview additionally uses Breadcrumb. Install it before copying the Code example, then save both page.tsx and _sidebar.tsx from that tab in the same directory. Its workspace metrics are illustrative, and the avatar uses initials so no image asset is required. Replace the sample navigation destinations with your application's routes.

npx shadcn@latest add https://neobrutal-ui.andongmin.com/r/breadcrumb.json

#Usage

import {
  SidebarProvider,
  Sidebar,
  SidebarContent,
  SidebarGroup,
  SidebarGroupLabel,
  SidebarGroupContent,
  SidebarMenu,
  SidebarMenuItem,
  SidebarMenuButton,
  SidebarInset,
  SidebarTrigger,
} from "@/components/ui/sidebar";

export default function ApplicationLayout() {
  return (
    <SidebarProvider>
      <Sidebar>
        <SidebarContent>
          <SidebarGroup>
            <SidebarGroupLabel>Workspace</SidebarGroupLabel>
            <SidebarGroupContent>
              <nav aria-label="Workspace navigation">
                <SidebarMenu>
                  <SidebarMenuItem>
                    <SidebarMenuButton render={<a href="/docs">Documentation</a>} />
                  </SidebarMenuItem>
                </SidebarMenu>
              </nav>
            </SidebarGroupContent>
          </SidebarGroup>
        </SidebarContent>
      </Sidebar>
      <SidebarInset>
        <header className="p-4">
          <SidebarTrigger />
        </header>
        <section className="p-4">
          <h1>Workspace overview</h1>
        </section>
      </SidebarInset>
    </SidebarProvider>
  );
}

#API reference

Prop / partPurposeDefault
SidebarProvider.defaultOpenInitial desktop expanded statetrue
SidebarProvider.open / onOpenChangeControlled desktop stateUncontrolled
Sidebar.sideleft or rightleft
Sidebar.variantsidebar, floating, or insetsidebar
Sidebar.collapsibleoffcanvas, icon, or noneoffcanvas
SidebarTrigger / useSidebarToggle and context accessProvider required
SidebarMenuButton.isActiveActive link stylingfalse
SidebarMenuButton.variantMenu button appearance: default or outlinedefault
SidebarMenuButton.sizeMenu button size: default, sm, or lgdefault
SidebarMenuAction.showOnHoverReveal the action on hover or keyboard focusfalse
SidebarMenuSubButton.sizeNested link size: sm or mdmd
SidebarMenuSubButton.isActiveActive nested-link stylingfalse

#Accessibility

Name navigation regions and give links destinations and readable labels. Collapsed icon-only items still need names. The mobile version behaves as a modal sheet; check focus and scroll at both sizes. Persistence is application-owned. Initialize defaultOpen or control open / onOpenChange from your own storage; the component does not write cookies.

In desktop offcanvas mode, collapsed navigation is hidden from keyboard focus and assistive technology. Keep a SidebarTrigger outside the sidebar so it can be reopened. SidebarRail remains available for pointer users.

onOpenChange also observes changes when open is uncontrolled. Trigger and rail click handlers run before toggling and can cancel it with event.preventDefault(). A disabled SidebarMenuButton stays disabled when it has a tooltip.

#Offcanvas navigation

Loading preview...