Wrap the app in SidebarProvider, then place a Sidebar and a SidebarInset. It collapses to an icon rail on desktop and a drawer on mobile, and flips sides in RTL.
When to use
Use Sidebar as the primary navigation of an authenticated application: an admin console, a case management tool, or a citizen dashboard with several sections. Wrap the app in SidebarProvider, place the Sidebar, and render pages inside SidebarInset.
For public sites with a few links, a header with SlideoutMenu on mobile is lighter.
Props
Props declared by Sidebar. Native attributes of the underlying element pass through.
<Sidebar>
| Prop | Type | Default | Description |
|---|
variant | "sidebar" | "floating" | "inset" | – | |
collapsible | "icon" | "none" | "offcanvas" | – | |
side | "start" | "end" | – | Logical side; flips with dir. Default 'start'. |
<SidebarProvider>
| Prop | Type | Default | Description |
|---|
defaultOpen | boolean | – | Uncontrolled initial desktop state. Default true (expanded). |
open | boolean | – | Controlled desktop open state. |
onOpenChange | (open: boolean) => void | – | |
mobileBreakpoint | number | – | Viewport width (px) below which the mobile Drawer engages. Default 768. |
keyboardShortcut | boolean | – | Register Cmd/Ctrl+B to toggle. Default true. |
<SidebarTrigger>
| Prop | Type | Default | Description |
|---|
asChild | boolean | – | |
<SidebarInset>
| Prop | Type | Default | Description |
|---|
asChild | boolean | – | |
scrollable | boolean | – | Make the inset its own vertical scroll region: tall content scrolls inside
it (the sidebar + footer stay put) with zero consumer layout CSS - no
flex / min-block-size:0 / overflow-y:auto boilerplate. The whole inset
scrolls, header included; for a fixed header with only the body scrolling,
leave this off and compose a nested scroll region inside the inset (see the
App shell story). |
<SidebarGroupAction>
| Prop | Type | Default | Description |
|---|
asChild | boolean | – | |
<SidebarMenuButton>
| Prop | Type | Default | Description |
|---|
size | "sm" | "md" | "lg" | – | |
asChild | boolean | – | |
isActive | boolean | – | |
tooltip | react.ReactNode | – | Tooltip content shown only when the rail is collapsed (desktop). |
<SidebarMenuAction>
| Prop | Type | Default | Description |
|---|
asChild | boolean | – | |
showOnHover | boolean | – | Reveal the action only on row hover/focus (CSS-driven). |
<SidebarMenuSkeleton>
| Prop | Type | Default | Description |
|---|
showIcon | boolean | – | |
<SidebarMenuSubButton>
| Prop | Type | Default | Description |
|---|
size | "sm" | "md" | – | |
asChild | boolean | – | |
isActive | boolean | – | |
Accessibility
Menus render as lists of buttons and links, and the active item is marked with aria-current. Collapsible groups expose aria-expanded. When collapsed to the icon rail, each item shows a tooltip so the label is still available.
The trigger has an accessible name, and SidebarProvider offers a keyboard shortcut you can set with keyboardShortcut. On mobile, the sidebar opens as a drawer with focus trapping.