Note: The sidebar is hidden by default on mobile — it slides in over the content with a backdrop when toggled. View these examples on desktop or use the SidebarTrigger to toggle visibility.
Copy to clipboard
Main content area
<Sidebar>
<SidebarHeader>
<div class="flex items-center gap-2 px-2">
<div class="size-6 rounded-md bg-primary"></div>
<span class="font-semibold">Acme Inc</span>
</div>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Home</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Inbox</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Settings</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</Sidebar>
<Sidebar>
<SidebarHeader>
<div class="flex items-center gap-2 px-2">
<div class="size-6 rounded-md bg-primary"></div>
<span class="font-semibold">Acme Inc</span>
</div>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Home</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Inbox</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Settings</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</Sidebar><Sidebar>
<SidebarHeader>
<div class="flex items-center gap-2 px-2">
<div class="size-6 rounded-md bg-primary"></div>
<span class="font-semibold">Acme Inc</span>
</div>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Home</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Inbox</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Settings</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</Sidebar>
Installation
Copy to clipboard
npx bearnie add sidebar
npx bearnie add sidebarnpx bearnie add sidebar
bunx bearnie add sidebar
bunx bearnie add sidebarbunx bearnie add sidebar
pnpm dlx bearnie add sidebar
pnpm dlx bearnie add sidebarpnpm dlx bearnie add sidebar
yarn dlx bearnie add sidebar
yarn dlx bearnie add sidebaryarn dlx bearnie add sidebar
Usage
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupLabel,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/bearnie/sidebar"<Sidebar>
<SidebarHeader>
<span>Logo</span>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Menu</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="/">
<HomeIcon />
<span>Home</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="/settings">
<SettingsIcon />
<span>Settings</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</Sidebar>Examples
With trigger
Use SidebarTrigger to toggle the sidebar.
Copy to clipboard
<Sidebar defaultOpen={true}>
<SidebarHeader>
<span class="px-2 font-semibold">App</span>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Dashboard</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<!-- In your main content -->
<SidebarTrigger />
<Sidebar defaultOpen={true}>
<SidebarHeader>
<span class="px-2 font-semibold">App</span>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Dashboard</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<!-- In your main content -->
<SidebarTrigger /><Sidebar defaultOpen={true}>
<SidebarHeader>
<span class="px-2 font-semibold">App</span>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Dashboard</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<!-- In your main content -->
<SidebarTrigger />
Icon rail
With collapsible="icon", collapsing the sidebar on desktop keeps a narrow rail showing just the icons — labels (any span inside a menu button) and group labels are hidden. Toggle it with the trigger to see it in action.
Copy to clipboard
<Sidebar collapsible="icon">
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<HomeIcon />
<span>Home</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<!-- In your main content -->
<SidebarTrigger />
<Sidebar collapsible="icon">
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<HomeIcon />
<span>Home</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<!-- In your main content -->
<SidebarTrigger /><Sidebar collapsible="icon">
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<HomeIcon />
<span>Home</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<!-- In your main content -->
<SidebarTrigger />
Persistent state
Give the sidebar a persist key and its open/collapsed state is saved to localStorage and restored on the next page load (desktop only — mobile always starts closed).
<Sidebar persist="app-sidebar" collapsible="icon">
...
</Sidebar>Multiple groups
Copy to clipboard
Content
<Sidebar>
<SidebarHeader>
<span class="px-2 font-semibold">Workspace</span>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Platform</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Dashboard</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Messages</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
<SidebarSeparator />
<SidebarGroup>
<SidebarGroupLabel>Projects</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Project Alpha</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<Sidebar>
<SidebarHeader>
<span class="px-2 font-semibold">Workspace</span>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Platform</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Dashboard</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Messages</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
<SidebarSeparator />
<SidebarGroup>
<SidebarGroupLabel>Projects</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Project Alpha</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar><Sidebar>
<SidebarHeader>
<span class="px-2 font-semibold">Workspace</span>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Platform</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#" isActive>
<span>Dashboard</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Messages</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
<SidebarSeparator />
<SidebarGroup>
<SidebarGroupLabel>Projects</SidebarGroupLabel>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton href="#">
<span>Project Alpha</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
</Sidebar>
Structure
Sidebar- Main container with collapsible stateSidebarHeader- Sticky header sectionSidebarContent- Scrollable content areaSidebarFooter- Sticky footer sectionSidebarGroup- Groups related menu itemsSidebarGroupLabel- Label for a groupSidebarMenu- Menu container (ul)SidebarMenuItem- Menu item wrapper (li)SidebarMenuButton- Clickable menu button/linkSidebarTrigger- Toggle buttonSidebarSeparator- Visual divider
Props
Sidebar
| Prop | Type | Default | Description |
|---|---|---|---|
| side | “left” | “right” | “left” | Side of the screen |
| collapsible | boolean | “icon” | true | true collapses off-canvas; "icon" collapses to an icon rail on desktop; false disables collapsing |
| defaultOpen | boolean | true | Initial open state |
| persist | string | - | localStorage key; saves and restores the open/collapsed state across page loads (desktop only) |
| class | string | - | Additional CSS classes |
SidebarMenuButton
| Prop | Type | Default | Description |
|---|---|---|---|
| href | string | - | Link URL (renders as anchor) |
| isActive | boolean | false | Active state styling |
| class | string | - | Additional CSS classes |
SidebarTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| for | string | - | ID of sidebar to target |
| class | string | - | Additional CSS classes |
Theming
The sidebar uses dedicated CSS variables for theming:
:root {
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.439 0 0);
}