On this page
const items = /* ... */;
<SidebarProvider className="h-[28rem] min-h-0 overflow-hidden rounded-lg border">
<Sidebar>
<SidebarHeader>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton size="lg" tooltip="Acme Inc">
<div className="flex aspect-square size-8 items-center justify-center rounded-md bg-primary text-fg-on-primary">
<SparklesIcon className="size-4" />
</div>
<div className="flex flex-col gap-0.5 leading-none">
<span className="font-medium text-fg">Acme Inc</span>
<span className="text-xs">Enterprise</span>
</div>
<ChevronsUpDownIcon className="ml-auto" />
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Platform</SidebarGroupLabel>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton
isActive={item.isActive}
tooltip={item.title}
>
<item.icon />
<span>{item.title}</span>
</SidebarMenuButton>
{item.badge && (
<SidebarMenuBadge>{item.badge}</SidebarMenuBadge>
)}
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton size="lg" tooltip="Mehdi">
<Avatar className="size-8">
<AvatarImage
src="https://github.com/mehdibha.png"
alt="Mehdi"
/>
<AvatarFallback>M</AvatarFallback>
</Avatar>
<div className="flex flex-col gap-0.5 leading-none">
<span className="font-medium text-fg">Mehdi</span>
<span className="text-xs">m@example.com</span>
</div>
<ChevronsUpDownIcon className="ml-auto" />
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</Sidebar>
<SidebarInset>
<header className="flex h-12 shrink-0 items-center gap-2 border-b px-3">
<SidebarTrigger />
<span className="text-sm font-medium">Dashboard</span>
</header>
<div className="flex flex-1 flex-col gap-3 p-3">
<div className="grid grid-cols-3 gap-3">
<div className="aspect-video rounded-lg bg-muted" />
<div className="aspect-video rounded-lg bg-muted" />
<div className="aspect-video rounded-lg bg-muted" />
</div>
<div className="flex-1 rounded-lg bg-muted" />
</div>
</SidebarInset>
</SidebarProvider>Installation
npx shadcn@latest add @dotui/sidebarAnatomy
A sidebar is built from a SidebarProvider wrapping the Sidebar and a SidebarInset (the main content). Inside the sidebar, compose a header, scrollable content split into groups of menus, and a footer.
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupLabel,
SidebarHeader,
SidebarInset,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarProvider,
SidebarTrigger,
} from '@/components/ui/sidebar'<SidebarProvider>
<Sidebar>
<SidebarHeader />
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Platform</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton>Dashboard</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter />
</Sidebar>
<SidebarInset>
<SidebarTrigger />
{/* page content */}
</SidebarInset>
</SidebarProvider>Usage
The Sidebar positions itself relative to the SidebarProvider, so the whole shell is self-contained. For a full-screen app, give the provider the viewport height and let the content scroll inside the inset:
<SidebarProvider className="h-svh">
<Sidebar>{/* ... */}</Sidebar>
<SidebarInset className="overflow-auto">{/* ... */}</SidebarInset>
</SidebarProvider>Below the md breakpoint the sidebar renders as an off-canvas drawer, toggled by the same SidebarTrigger. The sidebar can also be toggled from anywhere with ⌘+B (Ctrl+B).
Links
Pass href to SidebarMenuButton (or SidebarMenuSubButton) to render it as a link, and isActive to mark the current page (which also sets aria-current="page").
<SidebarMenuButton href="/dashboard" isActive>
<HomeIcon />
<span>Dashboard</span>
</SidebarMenuButton>useSidebar
Read or control the sidebar state from any descendant of SidebarProvider:
const {
state,
isOpen,
setOpen,
isMobile,
openMobile,
setOpenMobile,
toggleSidebar,
} = useSidebar()Controlled state
Drive the open state yourself with isOpen and onOpenChange on SidebarProvider — useful for persisting it (e.g. in a cookie or localStorage).
Examples
API Reference
SidebarProvider
Provides the sidebar's open/collapsed state to everything inside it and renders the layout wrapper. Wrap your whole app shell (the sidebar and its main content) in a single provider.
Supports all div attributes.
| Prop | Type | Default | |
|---|---|---|---|
Sidebar
The sidebar panel itself. Renders a fixed desktop panel and an off-canvas Drawer on mobile, driven by the nearest `SidebarProvider`.
Supports all nav attributes.
| Prop | Type | Default | |
|---|---|---|---|
"left" | "right" | 'left' | ||
"floating" | "inset" | "sidebar" | 'sidebar' | ||
"icon" | "none" | "offcanvas" | 'offcanvas' | ||
SidebarInset
The main content area that sits next to the sidebar. Required when using the `inset` variant; otherwise optional.
Supports all main attributes.
| Prop | Type | Default | |
|---|---|---|---|
SidebarTrigger
A button that toggles the sidebar open and closed.
| Prop | Type | Default | |
|---|---|---|---|
boolean | — | ||
ReactNode | function | — | ||
boolean | — | ||
SidebarRail
A thin, draggable rail along the inner edge of the sidebar that toggles it — a mouse-friendly alternative to the trigger.
| Prop | Type | Default | |
|---|---|---|---|
ReactNode | function | — | ||
boolean | — | ||
boolean | — | ||
SidebarHeader
A sticky header region at the top of the sidebar.
| Prop | Type | Default | |
|---|---|---|---|
SidebarFooter
SidebarContent
SidebarSeparator
A separator line styled to fit inside the sidebar.
| Prop | Type | Default | |
|---|---|---|---|
Orientation | 'horizontal' | ||
string | — | ||
SidebarGroup
A labelled section of the sidebar, grouping related menus.
Supports all div attributes.
| Prop | Type | Default | |
|---|---|---|---|
SidebarGroupLabel
The label/heading of a `SidebarGroup`. Hidden when collapsed to icons.
| Prop | Type | Default | |
|---|---|---|---|
number | 3 | ||
SidebarGroupAction
An action button anchored to the top-right of a `SidebarGroup`.
| Prop | Type | Default | |
|---|---|---|---|
ReactNode | function | — | ||
boolean | — | ||
boolean | — | ||
SidebarGroupContent
SidebarMenu
SidebarMenuItem
SidebarMenuButton
The interactive element inside a `SidebarMenuItem`. Renders a button, or a link when `href` is provided.
| Prop | Type | Default | |
|---|---|---|---|
boolean | — | ||
"lg" | "md" | "sm" | 'md' | ||
"default" | "outline" | 'default' | ||
ReactNode | TooltipContentProps | — | ||
boolean | — | ||
boolean | — | ||
SidebarMenuAction
An action button anchored to the right of a `SidebarMenuItem`.
| Prop | Type | Default | |
|---|---|---|---|
boolean | — | ||
ReactNode | function | — | ||
boolean | — | ||
boolean | — | ||
SidebarMenuBadge
A badge (e.g. a count) anchored to the right of a `SidebarMenuItem`.
Supports all div attributes.
| Prop | Type | Default | |
|---|---|---|---|
SidebarMenuSkeleton
A loading placeholder shaped like a `SidebarMenuButton`.
Supports all div attributes.
| Prop | Type | Default | |
|---|---|---|---|
boolean | — | ||
SidebarMenuSub
A nested list of sub-items, indented under a `SidebarMenuItem`.
Supports all ul attributes.
| Prop | Type | Default | |
|---|---|---|---|
SidebarMenuSubItem
SidebarMenuSubButton
The interactive element inside a `SidebarMenuSubItem`. Renders a button, or a link when `href` is provided.
| Prop | Type | Default | |
|---|---|---|---|
boolean | — | ||
"md" | "sm" | 'md' | ||
boolean | — | ||
boolean | — | ||
Last updated on 6/16/2026