Sidebar

A composable, collapsible sidebar for application layouts.

Sidebar
Overview

Good morning, Pedro

Here is a summary of your workspace.

Total revenue

$45,231.89

+20.1% from last month

Subscriptions

+2,350

+180.1% from last month

Sales

+12,234

+19% from last month

Active now

+573

+201 since last hour

Component Code
<april:sidebar-layout class="w-full min-w-0 flex-nowrap">
<april:sidebar variant="floating" collapsible="icon">
<slot:header>
<april:dropdown-menu x-teleport="body" class="w-full">
<slot:trigger>
<april:button variant="ghost" size="none"
class="h-10 w-full justify-between px-2 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:px-0">
<span class="flex min-w-0 items-center gap-2">
<span
class="flex size-7 shrink-0 items-center justify-center rounded-md bg-primary text-primary-foreground">
<x-lucide-layers-3 class="size-4" />
</span>
<span class="truncate font-semibold group-data-[collapsible=icon]:hidden">Acme Inc.</span>
</span>
<x-lucide-chevrons-up-down class="size-4 shrink-0 group-data-[collapsible=icon]:hidden" />
</april:button>
</slot:trigger>
<slot:content>
<april:dropdown-menu-label>Switch workspace</april:dropdown-menu-label>
<april:dropdown-menu-separator />
<april:dropdown-menu-item>Acme Inc.
<april:dropdown-menu-shortcut>⌘1</april:dropdown-menu-shortcut></april:dropdown-menu-item>
<april:dropdown-menu-item>Design team
<april:dropdown-menu-shortcut>⌘2</april:dropdown-menu-shortcut></april:dropdown-menu-item>
<april:dropdown-menu-separator />
<april:dropdown-menu-item>Create workspace</april:dropdown-menu-item>
</slot:content>
</april:dropdown-menu>
<april:sidebar-input class="mt-2 group-data-[collapsible=icon]:hidden" placeholder="Search..." />
</slot:header>
<slot:content>
<april:sidebar-group>
<april:sidebar-group-label>Workspace</april:sidebar-group-label>
<april:sidebar-group-content>
<april:sidebar-menu>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#" :active="true">
<x-lucide-layout-dashboard />
<span>Overview</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-inbox />
<span>Inbox</span>
<april:sidebar-menu-badge>12</april:sidebar-menu-badge>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-calendar />
<span>Calendar</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-chart-line />
<span>Analytics</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-folder-kanban />
<span>Projects</span>
<april:sidebar-menu-badge>8</april:sidebar-menu-badge>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-users />
<span>Customers</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
</april:sidebar-menu>
</april:sidebar-group-content>
</april:sidebar-group>
<april:sidebar-group>
<april:sidebar-group-label>Manage</april:sidebar-group-label>
<april:sidebar-group-content>
<april:sidebar-menu>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-users />
<span>Team</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-settings />
<span>Settings</span>
</april:sidebar-menu-button-link>
<april:sidebar-menu-action :show-on-hover="true"
aria-label="Settings actions">•••</april:sidebar-menu-action>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-circle-help />
<span>Help center</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-list />
<span>Activity log</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-sliders-horizontal />
<span>Preferences</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
</april:sidebar-menu>
</april:sidebar-group-content>
</april:sidebar-group>
</slot:content>
<slot:footer>
<april:dropdown-menu x-teleport="body" class="w-full">
<slot:trigger>
<april:button variant="ghost" size="none"
class="h-10 w-full justify-start gap-2 px-2 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:justify-center">
<april:avatar size="sm">
<slot:fallback>PD</slot:fallback>
</april:avatar>
<span class="min-w-0 text-left group-data-[collapsible=icon]:hidden"><span
class="block truncate text-sm font-medium">Pedro Duarte</span><span
class="block truncate text-xs text-muted-foreground">pedro@example.com</span></span>
</april:button>
</slot:trigger>
<slot:content>
<april:dropdown-menu-label>My account</april:dropdown-menu-label>
<april:dropdown-menu-separator />
<april:dropdown-menu-item>Profile</april:dropdown-menu-item>
<april:dropdown-menu-item>Billing</april:dropdown-menu-item>
<april:dropdown-menu-item>Sign out</april:dropdown-menu-item>
</slot:content>
</april:dropdown-menu>
</slot:footer>
<april:sidebar-rail />
</april:sidebar>
<april:sidebar-inset>
<header class="flex h-14 items-center justify-between border-b px-4">
<div class="flex items-center gap-2">
<april:sidebar-trigger />
<span class="text-sm text-muted-foreground">Overview</span>
</div>
<april:button size="sm"><x-lucide-plus class="mr-2 size-4" />New project</april:button>
</header>
<main class="space-y-6 p-4 lg:p-6">
<div>
<h2 class="text-2xl font-semibold tracking-tight">Good morning, Pedro</h2>
<p class="text-sm text-muted-foreground">Here is a summary of your workspace.</p>
</div>
<div class="grid gap-4 sm:grid-cols-2">
<april:card>
<slot:title class="text-sm font-medium">Total revenue</slot:title>
<slot:content>
<div class="text-2xl font-bold">$45,231.89</div>
<p class="text-xs text-muted-foreground">+20.1% from last month</p>
</slot:content>
</april:card>
<april:card>
<slot:title class="text-sm font-medium">Subscriptions</slot:title>
<slot:content>
<div class="text-2xl font-bold">+2,350</div>
<p class="text-xs text-muted-foreground">+180.1% from last month</p>
</slot:content>
</april:card>
<april:card>
<slot:title class="text-sm font-medium">Sales</slot:title>
<slot:content>
<div class="text-2xl font-bold">+12,234</div>
<p class="text-xs text-muted-foreground">+19% from last month</p>
</slot:content>
</april:card>
<april:card>
<slot:title class="text-sm font-medium">Active now</slot:title>
<slot:content>
<div class="text-2xl font-bold">+573</div>
<p class="text-xs text-muted-foreground">+201 since last hour</p>
</slot:content>
</april:card>
</div>
</main>
</april:sidebar-inset>
</april:sidebar-layout>

The sidebar is not one component. It is a set of parts you put together, so you can build the layout your app needs instead of the one I guessed you needed.

Anatomy

Wrap everything in sidebar-layout. It holds the open state, so the sidebar, the trigger and the page content all agree on whether the sidebar is open.

layout.blade.php
<april:sidebar-layout>
<april:sidebar>
<slot:header>...</slot:header>
<slot:content>
<april:sidebar-group>
<april:sidebar-group-label>Platform</april:sidebar-group-label>
<april:sidebar-group-content>
<april:sidebar-menu>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="/inbox">Inbox</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
</april:sidebar-menu>
</april:sidebar-group-content>
</april:sidebar-group>
</slot:content>
<slot:footer>...</slot:footer>
<april:sidebar-rail />
</april:sidebar>
<april:sidebar-inset>
<april:sidebar-trigger />
{{ $slot }}
</april:sidebar-inset>
<p>&lt;/april:sidebar-layout&gt;


Menus

A menu is a list. Use sidebar-menu-button-link for a link and sidebar-menu-button for a button. Mark the current page with :active="true".

Add a badge for a count, an action for a row menu, and a submenu for children. The skeleton is there for while your data loads.

Component Code
<april:sidebar collapsible="none" class="w-64 border rounded-lg">
<slot:content>
<april:sidebar-group>
<april:sidebar-group-label>Projects</april:sidebar-group-label>
<april:sidebar-group-action>+</april:sidebar-group-action>
<april:sidebar-group-content>
<april:sidebar-menu>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#" :active="true">Design system</april:sidebar-menu-button-link>
<april:sidebar-menu-badge>24</april:sidebar-menu-badge>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">Marketing site</april:sidebar-menu-button-link>
<april:sidebar-menu-action :show-on-hover="true">...</april:sidebar-menu-action>
<april:sidebar-menu-sub>
<april:sidebar-menu-sub-item>
<april:sidebar-menu-sub-button href="#">Landing page</april:sidebar-menu-sub-button>
</april:sidebar-menu-sub-item>
<april:sidebar-menu-sub-item>
<april:sidebar-menu-sub-button href="#" :active="true">Pricing</april:sidebar-menu-sub-button>
</april:sidebar-menu-sub-item>
</april:sidebar-menu-sub>
</april:sidebar-menu-item>
<april:sidebar-separator />
<april:sidebar-menu-item>
<april:sidebar-menu-skeleton :show-icon="true" />
</april:sidebar-menu-item>
</april:sidebar-menu>
</april:sidebar-group-content>
</april:sidebar-group>
</slot:content>
</april:sidebar>


Collapsible

The collapsible attribute decides what happens when the sidebar closes. It takes three values.

Offcanvas

The default. The sidebar slides off the screen.

Sidebar
Acme Inc

Collapse the sidebar to see it shrink to icon width.

Component Code
<april:sidebar-layout class="min-h-[620px] border rounded-lg overflow-hidden">
<april:sidebar collapsible="icon">
<slot:header>
<span class="font-semibold px-2">Acme Inc</span>
</slot:header>
<slot:content>
<april:sidebar-group>
<april:sidebar-group-label>Platform</april:sidebar-group-label>
<april:sidebar-group-content>
<april:sidebar-menu>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#" :active="true">
<x-lucide-inbox />
<span>Inbox</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">
<x-lucide-calendar />
<span>Calendar</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
</april:sidebar-menu>
</april:sidebar-group-content>
</april:sidebar-group>
</slot:content>
<april:sidebar-rail />
</april:sidebar>
<april:sidebar-inset class="p-4">
<april:sidebar-trigger />
<p class="mt-4 text-sm text-muted-foreground">Collapse the sidebar to see it shrink to icon width.</p>
</april:sidebar-inset>
</april:sidebar-layout>


Icon

The sidebar shrinks to icon width and keeps the icons visible. Labels, badges, actions and submenus hide themselves.

<april:sidebar collapsible="icon">...</april:sidebar>

None

The sidebar never collapses. Use it when you want a plain, always open panel.

<april:sidebar collapsible="none">...</april:sidebar>

Side

Use the side attribute to put the sidebar on the right. The border, the rail and the mobile panel all follow.

The sidebar sits on the right.

Sidebar
Acme Inc
Component Code
<april:sidebar-layout class="min-h-[620px] border rounded-lg overflow-hidden">
<april:sidebar-inset class="p-4">
<april:sidebar-trigger />
<p class="mt-4 text-sm text-muted-foreground">The sidebar sits on the right.</p>
</april:sidebar-inset>
<april:sidebar side="right">
<slot:header>
<span class="font-semibold px-2">Acme Inc</span>
</slot:header>
<slot:content>
<april:sidebar-group>
<april:sidebar-group-content>
<april:sidebar-menu>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">Inbox</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
</april:sidebar-menu>
</april:sidebar-group-content>
</april:sidebar-group>
</slot:content>
<april:sidebar-rail />
</april:sidebar>
</april:sidebar-layout>


Variants

The variant attribute takes sidebar, floating or inset. floating rounds the panel and gives it a border. inset pulls the page content in and rounds it instead.

Sidebar
Acme Inc

The floating variant rounds the panel and adds a border.

Component Code
<april:sidebar-layout class="min-h-[620px] border rounded-lg overflow-hidden">
<april:sidebar variant="floating" collapsible="icon">
<slot:header>
<span class="font-semibold px-2">Acme Inc</span>
</slot:header>
<slot:content>
<april:sidebar-group>
<april:sidebar-group-content>
<april:sidebar-menu>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#" :active="true">
<x-lucide-inbox />
<span>Inbox</span>
</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
</april:sidebar-menu>
</april:sidebar-group-content>
</april:sidebar-group>
</slot:content>
</april:sidebar>
<april:sidebar-inset class="p-4">
<april:sidebar-trigger />
<p class="mt-4 text-sm text-muted-foreground">The floating variant rounds the panel and adds a border.</p>
</april:sidebar-inset>
</april:sidebar-layout>


Search

sidebar-input is the input component with the sidebar sizing already applied.

Component Code
<april:sidebar collapsible="none" class="w-64 border rounded-lg">
<slot:header>
<april:sidebar-input name="search" placeholder="Search the docs..." />
</slot:header>
<slot:content>
<april:sidebar-group>
<april:sidebar-group-content>
<april:sidebar-menu>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">Installation</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
<april:sidebar-menu-item>
<april:sidebar-menu-button-link href="#">Theming</april:sidebar-menu-button-link>
</april:sidebar-menu-item>
</april:sidebar-menu>
</april:sidebar-group-content>
</april:sidebar-group>
</slot:content>
</april:sidebar>


Opening and closing

Three things toggle the sidebar:

  • sidebar-trigger, a button you can put anywhere inside the layout
  • sidebar-rail, the thin strip along the sidebar edge
  • Ctrl + B, or Cmd + B on a Mac

On a screen narrower than 768px the sidebar becomes a panel that slides in over the page. The same three things still open it.

Start the sidebar closed with :default-open="false".

<april:sidebar-layout :default-open="false">...</april:sidebar-layout>

Persisting state

To keep the sidebar open or collapsed across page loads, pass x-persist with a unique key. The component applies the x-persist directive to both the desktop and mobile sidebars for you.

<april:sidebar x-persist="app-sidebar">...</april:sidebar>

Width

The sidebar reads three CSS variables. Set them on sidebar-layout to change the width for one sidebar:

<april:sidebar-layout width="20rem" width-icon="4rem">...</april:sidebar-layout>

Or set them in your CSS to change every sidebar:

app.css
:root {
--sidebar-width: 16rem;
--sidebar-width-icon: 3rem;
--sidebar-width-mobile: 18rem;
}

Styling from your own CSS

Every part carries a data-slot attribute, and the sidebar carries its state. You can style any part without touching the markup:

app.css
/* The menu button of the current page */
[data-slot="sidebar-menu-button"][data-active="true"] {
font-weight: 600;
}
<p>/* Only while the sidebar is collapsed */
[data-slot=&quot;sidebar&quot;][data-state=&quot;collapsed&quot;] [data-slot=&quot;sidebar-header&quot;] {
justify-content: center;
}

See Data attributes for the full list.

Publishing Views

Use the following commands to publish these views:

php artisan april:publish sidebar-layout
php artisan april:publish sidebar
php artisan april:publish sidebar-trigger
php artisan april:publish sidebar-rail
php artisan april:publish sidebar-inset
php artisan april:publish sidebar-input
php artisan april:publish sidebar-separator
php artisan april:publish sidebar-group
php artisan april:publish sidebar-group-label
php artisan april:publish sidebar-group-action
php artisan april:publish sidebar-group-content
php artisan april:publish sidebar-menu
php artisan april:publish sidebar-menu-item
php artisan april:publish sidebar-menu-button
php artisan april:publish sidebar-menu-button-link
php artisan april:publish sidebar-menu-action
php artisan april:publish sidebar-menu-badge
php artisan april:publish sidebar-menu-skeleton
php artisan april:publish sidebar-menu-sub
php artisan april:publish sidebar-menu-sub-item
php artisan april:publish sidebar-menu-sub-button
April UI keeps package views in `vendor/` by default. The command uses Laravel's vendor publishing system and copies overrides to `resources/views/vendor/april/components`. To publish all components, run:
php artisan april:publish --all
Review local overrides after an upgrade with `php artisan april:update --diff`.