sidebar.tsx.
We now have a solid foundation to build on top of. Composable. Themeable.
Customizable.
Browse the Blocks Library.
Installation
Structure
ASidebar component is composed of the following parts:
SidebarProvider- Handles collapsible state.Sidebar- The sidebar container.SidebarHeaderandSidebarFooter- Sticky at the top and bottom of the sidebar.SidebarContent- Scrollable content.SidebarGroup- Section within theSidebarContent.SidebarTrigger- Trigger for theSidebar.
Usage
app/layout.tsx
components/app-sidebar.tsx
Your First Sidebar
Let’s start with the most basic sidebar. A collapsible sidebar with a menu.import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { AppSidebar } from "@/components/app-sidebar"
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<SidebarProvider>
<AppSidebar />
<main>
<SidebarTrigger />
{children}
</main>
</SidebarProvider>
)
}
import { Sidebar, SidebarContent } from "@/components/ui/sidebar"
export function AppSidebar() {
return (
<Sidebar>
<SidebarContent />
</Sidebar>
)
}
import { Calendar, Home, Inbox, Search, Settings } from "lucide-react"
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar"
// Menu items.
const items = [
{
title: "Home",
url: "#",
icon: Home,
},
{
title: "Inbox",
url: "#",
icon: Inbox,
},
{
title: "Calendar",
url: "#",
icon: Calendar,
},
{
title: "Search",
url: "#",
icon: Search,
},
{
title: "Settings",
url: "#",
icon: Settings,
},
]
export function AppSidebar() {
return (
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
<a href={item.url}>
<item.icon />
<span>{item.title}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
)
}
Components
The components insidebar.tsx are built to be composable i.e you build your sidebar by putting the provided components together. They also compose well with other shadcn/ui components such as DropdownMenu, Collapsible or Dialog etc.
If you need to change the code in sidebar.tsx, you are encouraged to do so. The code is yours. Use sidebar.tsx as a starting point and build your own.
In the next sections, we’ll go over each component and how to use them.
SidebarProvider
TheSidebarProvider component is used to provide the sidebar context to the Sidebar component. You should always wrap your application in a SidebarProvider component.
Props
| Name | Type | Description |
|---|---|---|
defaultOpen | boolean | Default open state of the sidebar. |
open | boolean | Open state of the sidebar (controlled). |
onOpenChange | (open: boolean) => void | Sets open state of the sidebar (controlled). |
Width
If you have a single sidebar in your application, you can use theSIDEBAR_WIDTH and SIDEBAR_WIDTH_MOBILE variables in sidebar.tsx to set the width of the sidebar.
components/ui/sidebar.tsx
style prop to set the width of the sidebar.
To set the width of the sidebar, you can use the --sidebar-width and --sidebar-width-mobile CSS variables in the style prop.
components/ui/sidebar.tsx
Keyboard Shortcut
TheSIDEBAR_KEYBOARD_SHORTCUT variable is used to set the keyboard shortcut used to open and close the sidebar.
To trigger the sidebar, you use the cmd+b keyboard shortcut on Mac and ctrl+b on Windows.
You can change the keyboard shortcut by updating the SIDEBAR_KEYBOARD_SHORTCUT variable.
components/ui/sidebar.tsx
Persisted State
TheSidebarProvider supports persisting the sidebar state across page reloads and server-side rendering. It uses cookies to store the current state of the sidebar. When the sidebar state changes, a default cookie named sidebar_state is set with the current open/closed state. This cookie is then read on subsequent page loads to restore the sidebar state.
To persist sidebar state in Next.js, set up your SidebarProvider in app/layout.tsx like this:
app/layout.tsx
SIDEBAR_COOKIE_NAME variable in sidebar.tsx.
components/ui/sidebar.tsx
Sidebar
The mainSidebar component used to render a collapsible sidebar.
showLineNumbers
Props
| Property | Type | Description |
|---|---|---|
side | left or right | The side of the sidebar. |
variant | sidebar, floating, or inset | The variant of the sidebar. |
collapsible | offcanvas, icon, or none | Collapsible state of the sidebar. |
side
Use theside prop to change the side of the sidebar.
Available options are left and right.
showLineNumbers
variant
Use thevariant prop to change the variant of the sidebar.
Available options are sidebar, floating and inset.
showLineNumbers
Note: If you use the
inset variant, remember to wrap your main content
in a SidebarInset component.showLineNumbers
collapsible
Use thecollapsible prop to make the sidebar collapsible.
Available options are offcanvas, icon and none.
showLineNumbers
| Prop | Description |
|---|---|
offcanvas | A collapsible sidebar that slides in from the left or right. |
icon | A sidebar that collapses to icons. |
none | A non-collapsible sidebar. |
useSidebar
TheuseSidebar hook is used to control the sidebar.
showLineNumbers
| Property | Type | Description |
|---|---|---|
state | expanded or collapsed | The current state of the sidebar. |
open | boolean | Whether the sidebar is open. |
setOpen | (open: boolean) => void | Sets the open state of the sidebar. |
openMobile | boolean | Whether the sidebar is open on mobile. |
setOpenMobile | (open: boolean) => void | Sets the open state of the sidebar on mobile. |
isMobile | boolean | Whether the sidebar is on mobile. |
toggleSidebar | () => void | Toggles the sidebar. Desktop and mobile. |
SidebarHeader
Use theSidebarHeader component to add a sticky header to the sidebar.
The following example adds a <DropdownMenu> to the SidebarHeader.
components/app-sidebar.tsx
SidebarFooter
Use theSidebarFooter component to add a sticky footer to the sidebar.
The following example adds a <DropdownMenu> to the SidebarFooter.
components/app-sidebar.tsx
SidebarContent
TheSidebarContent component is used to wrap the content of the sidebar. This is where you add your SidebarGroup components. It is scrollable.
showLineNumbers
SidebarGroup
Use theSidebarGroup component to create a section within the sidebar.
A SidebarGroup has a SidebarGroupLabel, a SidebarGroupContent and an optional SidebarGroupAction.
showLineNumbers
Collapsible SidebarGroup
To make aSidebarGroup collapsible, wrap it in a Collapsible.
showLineNumbers
Note: We wrap the
CollapsibleTrigger in a SidebarGroupLabel to render
a button.SidebarGroupAction
Use theSidebarGroupAction component to add an action button to the SidebarGroup.
showLineNumbers
SidebarMenu
TheSidebarMenu component is used for building a menu within a SidebarGroup.
A SidebarMenu component is composed of SidebarMenuItem, SidebarMenuButton, <SidebarMenuAction /> and <SidebarMenuSub /> components.
Here’s an example of a SidebarMenu component rendering a list of projects.
showLineNumbers
SidebarMenuButton
TheSidebarMenuButton component is used to render a menu button within a SidebarMenuItem.
Link or Anchor
By default, theSidebarMenuButton renders a button but you can use the asChild prop to render a different component such as a Link or an a tag.
showLineNumbers
Icon and Label
You can render an icon and a truncated label inside the button. Remember to wrap the label in a<span>.
showLineNumbers
isActive
Use theisActive prop to mark a menu item as active.
showLineNumbers
SidebarMenuAction
TheSidebarMenuAction component is used to render a menu action within a SidebarMenuItem.
This button works independently of the SidebarMenuButton i.e you can have the <SidebarMenuButton /> as a clickable link and the <SidebarMenuAction /> as a button.
showLineNumbers
DropdownMenu
Here’s an example of aSidebarMenuAction component rendering a DropdownMenu.
showLineNumbers
SidebarMenuSub
TheSidebarMenuSub component is used to render a submenu within a SidebarMenu.
Use <SidebarMenuSubItem /> and <SidebarMenuSubButton /> to render a submenu item.
showLineNumbers
Collapsible SidebarMenu
To make aSidebarMenu component collapsible, wrap it and the SidebarMenuSub components in a Collapsible.
showLineNumbers
SidebarMenuBadge
TheSidebarMenuBadge component is used to render a badge within a SidebarMenuItem.
showLineNumbers
SidebarMenuSkeleton
TheSidebarMenuSkeleton component is used to render a skeleton for a SidebarMenu. You can use this to show a loading state when using React Server Components, SWR or react-query.
showLineNumbers
SidebarSeparator
TheSidebarSeparator component is used to render a separator within a Sidebar.
showLineNumbers
SidebarTrigger
Use theSidebarTrigger component to render a button that toggles the sidebar.
The SidebarTrigger component must be used within a SidebarProvider.
showLineNumbers
Custom Trigger
To create a custom trigger, you can use theuseSidebar hook.
showLineNumbers
SidebarRail
TheSidebarRail component is used to render a rail within a Sidebar. This rail can be used to toggle the sidebar.
showLineNumbers
Data Fetching
React Server Components
Here’s an example of aSidebarMenu component rendering a list of projects using React Server Components.
Skeleton to show loading state.
Server component fetching data.
Usage with React Suspense.
SWR and React Query
You can use the same approach with SWR or react-query.SWR
React Query
Controlled Sidebar
Use theopen and onOpenChange props to control the sidebar.
showLineNumbers
Theming
We use the following CSS variables to theme the sidebar.Styling
Here are some tips for styling the sidebar based on different states.- Styling an element based on the sidebar collapsible state. The following will hide the
SidebarGroupwhen the sidebar is iniconmode.
- Styling a menu action based on the menu button active state. The following will force the menu action to be visible when the menu button is active.
Changelog
2024-10-30 Cookie handling in setOpen
- #5593 - Improved setOpen callback logic in
<SidebarProvider>.
setOpen callback in <SidebarProvider> as follows:
showLineNumbers
2024-10-21 Fixed text-sidebar-foreground
- #5491 - Moved
text-sidebar-foregroundfrom<SidebarProvider>to<Sidebar>component.
2024-10-20 Typo in useSidebar hook.
Fixed typo in useSidebar hook.
sidebar.tsx

