Skip to main content

Sidebar

A composable, collapsible sidebar for application shells — with a mobile drawer, icon mode, and keyboard toggle.

On this page
Dashboard
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/sidebar

Anatomy

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).

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

Hover the icons
Floating
Inset
Aligned right
Groups
Nested items
Badges & actions
Search
User menu
Loading
Drag the rail to toggle
State: expanded

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.

PropType

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.

PropType
"left" | "right"
"floating" | "inset" | "sidebar"
"icon" | "none" | "offcanvas"

SidebarInset

The main content area that sits next to the sidebar. Required when using the `inset` variant; otherwise optional.

Supports all main attributes.

PropType

SidebarTrigger

A button that toggles the sidebar open and closed.

PropType
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.

PropType
ReactNode | function
boolean
boolean

SidebarHeader

A sticky header region at the top of the sidebar.

PropType

SidebarFooter

A sticky footer region at the bottom of the sidebar.

Supports all div attributes.

PropType

SidebarContent

The scrollable region between the header and footer.

Supports all div attributes.

PropType

SidebarSeparator

A separator line styled to fit inside the sidebar.

PropType
Orientation
string

SidebarGroup

A labelled section of the sidebar, grouping related menus.

Supports all div attributes.

PropType

SidebarGroupLabel

The label/heading of a `SidebarGroup`. Hidden when collapsed to icons.

PropType
number

SidebarGroupAction

An action button anchored to the top-right of a `SidebarGroup`.

PropType
ReactNode | function
boolean
boolean

SidebarGroupContent

The content wrapper inside a `SidebarGroup`.

Supports all div attributes.

PropType

SidebarMenu

The list element that holds `SidebarMenuItem`s.

Supports all ul attributes.

PropType

SidebarMenuItem

A single item (list element) in a `SidebarMenu`.

Supports all li attributes.

PropType

SidebarMenuButton

The interactive element inside a `SidebarMenuItem`. Renders a button, or a link when `href` is provided.

PropType
boolean
"lg" | "md" | "sm"
"default" | "outline"
ReactNode | TooltipContentProps
boolean
boolean

SidebarMenuAction

An action button anchored to the right of a `SidebarMenuItem`.

PropType
boolean
ReactNode | function
boolean
boolean

SidebarMenuBadge

A badge (e.g. a count) anchored to the right of a `SidebarMenuItem`.

Supports all div attributes.

PropType

SidebarMenuSkeleton

A loading placeholder shaped like a `SidebarMenuButton`.

Supports all div attributes.

PropType
boolean

SidebarMenuSub

A nested list of sub-items, indented under a `SidebarMenuItem`.

Supports all ul attributes.

PropType

SidebarMenuSubItem

A single item (list element) in a `SidebarMenuSub`.

Supports all li attributes.

PropType

SidebarMenuSubButton

The interactive element inside a `SidebarMenuSubItem`. Renders a button, or a link when `href` is provided.

PropType
boolean
"md" | "sm"
boolean
boolean

Last updated on 6/16/2026