SidebarLayout
SidebarLayout is the default layout component that provides a responsive sidebar navigation, breadcrumb trail, and theme toggle. It's designed to work seamlessly with AppShell's module system.
Import
import { SidebarLayout } from "@tailor-platform/app-shell";Basic Usage
import { AppShell, SidebarLayout } from "@tailor-platform/app-shell";
function App() {
return (
<AppShell modules={modules}>
<SidebarLayout />
</AppShell>
);
}This gives you:
- ✅ Responsive sidebar with auto-generated navigation from modules
- ✅ Breadcrumb navigation
- ✅ Theme toggle (light/dark mode)
- ✅ Mobile-friendly collapsible sidebar
Props
children
- Type:
(props: { Outlet: () => React.ReactNode }) => React.ReactNode(optional) - Description: Custom content renderer for adding headers, footers, or wrapping the outlet
<SidebarLayout>
{({ Outlet }) => (
<>
<CustomHeader />
<Outlet />
<CustomFooter />
</>
)}
</SidebarLayout>The Outlet component renders your current route's component.
sidebar
- Type:
React.ReactNode(optional) - Default:
<SidebarLayout.DefaultSidebar /> - Description: Replaces the whole sidebar region. Omit it for the built-in sidebar.
import { SidebarLayout, SidebarItem } from "@tailor-platform/app-shell";
<SidebarLayout
sidebar={
<SidebarLayout.DefaultSidebar>
<SidebarItem label="Custom Link" href="/custom" />
</SidebarLayout.DefaultSidebar>
}
/>;
SidebarLayout.DefaultSidebaris the same component as the top-levelDefaultSidebarexport (kept for backwards compatibility). The namespaced form is preferred for discoverability — it pairs withSidebarLayout.DefaultHeader.
defaultOpen
- Type:
boolean(optional) - Default:
true - Description: Whether the sidebar is open by default on desktop. Has no effect when
collapsibleisfalse.
// Sidebar closed by default on desktop
<SidebarLayout defaultOpen={false} />collapsible
- Type:
boolean(optional) - Default:
true - Description: Whether the sidebar can be collapsed. When set to
false, the sidebar is always visible and toggle buttons are hidden.defaultOpenis ignored when this isfalse.
// Non-collapsible sidebar (always visible, toggle buttons hidden)
<SidebarLayout collapsible={false} />header
- Type:
React.ReactNode(optional) - Default:
<SidebarLayout.DefaultHeader /> - Description: Replaces the whole top-bar region. Omit it for the built-in header.
Like sidebar, header is a full-region slot. There are three levels of customization:
1. Default — omit header entirely:
<SidebarLayout />2. Extend the built-in header — pass SidebarLayout.DefaultHeader and use its actions slot. This is the common case (e.g. adding a notification bell) and keeps the trigger + breadcrumb without reconstructing them:
import { SidebarLayout, AppearanceSwitcher, Button } from "@tailor-platform/app-shell";
import { BellIcon } from "lucide-react";
<SidebarLayout
header={
<SidebarLayout.DefaultHeader
actions={[
<Button key="bell" variant="outline" size="icon" aria-label="Notifications">
<BellIcon />
</Button>,
// `actions` REPLACES the default right-hand cluster, so include the
// appearance switcher explicitly to keep it.
<AppearanceSwitcher key="appearance" />,
]}
/>
}
/>;3. Replace it entirely — supply your own node:
<SidebarLayout header={<MyCustomHeader />} />SidebarLayout.DefaultHeader
The built-in header: sidebar trigger + breadcrumb on the left, and the actions cluster on the right.
actions—React.ReactNode | React.ReactNode[](optional). The entire right-hand cluster, laid out in a horizontal, vertically-centered row with consistent spacing.- Default:
[<AppearanceSwitcher />]— so out-of-the-box behavior is unchanged. - ⚠️
actionsreplaces the whole right-hand cluster, including the appearance switcher. If you pass your own actions and still want the switcher, include<AppearanceSwitcher />in the array (it is a public export).actions={[]}renders an empty right side.
- Default:
This is the supported extension point for the top bar — it replaces fragile workarounds that queried the header DOM and injected a React portal.
Features
Responsive Sidebar
The sidebar automatically adapts to different screen sizes:
- Desktop (≥ 768px): Full sidebar visible by default
- Tablet/Mobile (< 768px): Collapsible sidebar with hamburger menu
Users can toggle the sidebar using:
- Hamburger menu button (top left)
- Keyboard shortcut:
Cmd + B/Ctrl + B
Breadcrumb Navigation
Breadcrumbs are automatically generated based on the current route:
Dashboard > Products > Product DetailsBreadcrumbs update automatically as users navigate through your application.
Theme Toggle
The built-in header renders an AppearanceSwitcher — a palette-icon button whose dropdown switches the color theme (persisted to localStorage). To add your own controls (notifications, user menu, etc.) alongside it, pass SidebarLayout.DefaultHeader with an actions array that includes <AppearanceSwitcher />.
Customization Examples
Custom Header and Footer
import { SidebarLayout } from "@tailor-platform/app-shell";
const CustomHeader = () => (
<div className="astw:bg-blue-500 astw:text-white astw:p-4">
<h2>Welcome to My App</h2>
</div>
);
const CustomFooter = () => (
<footer className="astw:p-4 astw:text-sm astw:text-gray-600">© 2026 My Company</footer>
);
function App() {
return (
<AppShell modules={modules}>
<SidebarLayout>
{({ Outlet }) => (
<div className="astw:flex astw:flex-col astw:h-full">
<CustomHeader />
<main className="astw:flex-1 astw:overflow-auto">
<Outlet />
</main>
<CustomFooter />
</div>
)}
</SidebarLayout>
</AppShell>
);
}Custom Sidebar
import {
SidebarLayout,
DefaultSidebar,
SidebarItem,
SidebarGroup,
SidebarSeparator,
} from "@tailor-platform/app-shell";
import { HelpCircle, ExternalLink } from "lucide-react";
function App() {
return (
<AppShell modules={modules}>
<SidebarLayout
sidebar={
<DefaultSidebar>
{/* Auto-generated navigation from modules */}
{/* Add custom items */}
<SidebarSeparator />
<SidebarGroup label="Help">
<SidebarItem
label="Documentation"
icon={<HelpCircle />}
href="https://docs.example.com"
external
/>
<SidebarItem
label="Support"
icon={<ExternalLink />}
href="https://support.example.com"
external
/>
</SidebarGroup>
</DefaultSidebar>
}
/>
</AppShell>
);
}Wrapping Content in a Container
<SidebarLayout>
{({ Outlet }) => (
<div className="astw:container astw:mx-auto astw:p-6 astw:max-w-7xl">
<Outlet />
</div>
)}
</SidebarLayout>Adding a Global Banner
<SidebarLayout>
{({ Outlet }) => (
<>
<div className="astw:bg-yellow-100 astw:border-b astw:border-yellow-200 astw:p-3 astw:text-center">
<p className="astw:text-sm">🎉 New features available! Check out our latest updates.</p>
</div>
<Outlet />
</>
)}
</SidebarLayout>Layout Structure
The SidebarLayout component creates the following structure:
┌─────────────────────────────────────────────┐
│ Sidebar │ Header (Breadcrumbs + │
│ │ Theme Toggle) │
│ - Dashboard ├─────────────────────────┤
│ - Products │ │
│ - Orders │ │
│ │ Page Content │
│ [Settings ▼] │ (Outlet) │
│ │ │
│ │ │
└─────────────────────────────────────────────┘Mobile view (sidebar collapsed):
┌─────────────────────────────────┐
│ [☰] Breadcrumbs [Theme] │
├─────────────────────────────────┤
│ │
│ Page Content │
│ (Outlet) │
│ │
└─────────────────────────────────┘Styling
The sidebar and layout use Tailwind CSS classes prefixed with astw: to avoid conflicts with your application styles.
To customize the appearance, you can:
Override CSS variables in your theme.css:
css:root { --sidebar-width: 280px; /* Default: 256px */ }Use custom sidebar component with your own styling
Wrap Outlet with container classes as shown in examples above
Accessibility
SidebarLayout includes built-in accessibility features:
- Keyboard navigation: Navigate sidebar items with arrow keys
- ARIA labels: Proper labels for screen readers
- Focus management: Focus trap when sidebar is open on mobile
- Responsive: Works with keyboard and touch inputs
Related Components
- AppShell - Root component
- DefaultHeader - Built-in header (
SidebarLayout.DefaultHeader) - DefaultSidebar - Built-in sidebar (
SidebarLayout.DefaultSidebar) - AppearanceSwitcher - Color-theme dropdown, composable into header
actions - SidebarItem - Individual sidebar navigation items
- SidebarGroup - Group sidebar items
Related Concepts
- Modules and Resources - How navigation is generated
- Routing and Navigation - Navigation between pages
- Styling and Theming - Customize appearance
API Reference
- useTheme - Access theme context