mdxui

Shell

App shell layout with sidebar and header

Shell

The Shell component provides the standard application layout with sidebar navigation, top header, and main content area. It's the structural foundation for all authenticated views.

Type Signature

interface ShellProps {
  /** Show sidebar */
  sidebar?: boolean
  /** Show header */
  header?: boolean
  /** Sidebar collapsed by default */
  sidebarCollapsed?: boolean
  /** Child content */
  children: React.ReactNode
}

Usage

<App name="Acme Dashboard">
  <Shell>
    <Dashboard />
  </Shell>
</App>

Props

Controls whether the sidebar is rendered. Defaults to true.

// Show sidebar (default)
<Shell>
  <Dashboard />
</Shell>

// Hide sidebar
<Shell sidebar={false}>
  <Dashboard />
</Shell>

Controls whether the header is rendered. Defaults to true.

// Show header (default)
<Shell>
  <Dashboard />
</Shell>

// Hide header
<Shell header={false}>
  <Dashboard />
</Shell>

sidebarCollapsed

Sets the initial collapsed state of the sidebar. Defaults to false.

// Sidebar expanded (default)
<Shell>
  <Dashboard />
</Shell>

// Sidebar collapsed by default
<Shell sidebarCollapsed={true}>
  <Dashboard />
</Shell>

children

The main content area. Typically contains View components like Dashboard, Settings, etc.

<Shell>
  <Dashboard>
    {/* Dashboard content */}
  </Dashboard>
</Shell>

Layout Structure

The Shell component implements this layout:

┌─────────────────────────────────────┐
│            Header                   │
├──────────┬──────────────────────────┤
│          │                          │
│ Sidebar  │         Main             │
│          │                          │
│          │                          │
└──────────┴──────────────────────────┘

With Collapsed Sidebar

When the sidebar is collapsed, it shows icons only:

┌─────────────────────────────────────┐
│            Header                   │
├───┬─────────────────────────────────┤
│ S │                                 │
│ i │          Main                   │
│ d │                                 │
│ e │                                 │
└───┴─────────────────────────────────┘

Header Hidden

When the header is hidden:

┌──────────┬──────────────────────────┐
│          │                          │
│ Sidebar  │         Main             │
│          │                          │
│          │                          │
└──────────┴──────────────────────────┘

Full-Screen Mode

When both sidebar and header are hidden:

┌─────────────────────────────────────┐
│                                     │
│             Main                    │
│                                     │
│                                     │
└─────────────────────────────────────┘

Common Patterns

Standard Application Layout

Most applications use the default Shell configuration:

<App name="Acme Dashboard">
  <Shell>
    <Dashboard />
  </Shell>
</App>

Full-Screen View

For immersive experiences (editors, canvas, etc.):

<Shell sidebar={false} header={false}>
  <EditorView />
</Shell>

Presentation Mode

Hide sidebar but keep header for context:

<Shell sidebar={false}>
  <PresentationView />
</Shell>

Compact Mode

Start with sidebar collapsed for more content space:

<Shell sidebarCollapsed={true}>
  <Dashboard />
</Shell>

View Layouts

The Shell provides the container, but Views determine their internal layout:

Single Layout

┌─────────────────────────────────┐
│             main                │
└─────────────────────────────────┘

Example: Dashboard, Settings

Column Layout

┌───────────────┬─────────────────┐
│    sidebar    │      main       │
└───────────────┴─────────────────┘

Example: List + Detail views

Canvas Layout

┌─────────────────────────────────┐
│              top                │
├─────────┬───────────────────────┤
│ sidebar │         main          │
└─────────┴───────────────────────┘

Example: Workflow editor, Design tools

Vibe Layout

┌─────────┬───────────┬──────────┐
│  chat   │  preview  │   code   │
└─────────┴───────────┴──────────┘

Example: VibeCode editor

See View Layouts for complete details.

Responsive Behavior

The Shell adapts to different screen sizes:

Desktop (≥1024px)

┌────────────────────────────────────┐
│            Header                  │
├─────────┬──────────────────────────┤
│ Sidebar │        Main              │
│ (240px) │                          │
└─────────┴──────────────────────────┘

Tablet (768px - 1023px)

┌────────────────────────────────────┐
│            Header                  │
├───┬────────────────────────────────┤
│ S │          Main                  │
│ b │                                │
└───┴────────────────────────────────┘
Sidebar collapsed to icons (60px)

Mobile (under 768px)

┌────────────────────────────────────┐
│ ☰  Header                          │
├────────────────────────────────────┤
│                                    │
│            Main                    │
│                                    │
└────────────────────────────────────┘
Sidebar slides over as drawer

State Management

The Shell manages several pieces of UI state:

interface SidebarState {
  collapsed: boolean      // Is sidebar collapsed?
  mobile: boolean         // Is mobile drawer open?
  width: number          // Sidebar width in pixels
}
interface NavigationState {
  currentPath: string    // Active route
  breadcrumbs: Crumb[]  // Breadcrumb trail
}

Customization

Custom Sidebar Width

Override the default sidebar width:

<Shell className="[--sidebar-width:280px]">
  <Dashboard />
</Shell>

Custom Breakpoints

Control when sidebar collapses:

<Shell className="[--sidebar-collapse-at:900px]">
  <Dashboard />
</Shell>

Integration with Components

The Shell automatically renders the <Sidebar> component with navigation items:

// Shell internally does:
<Sidebar
  nav={navigationItems}
  collapsed={sidebarCollapsed}
  onCollapse={handleCollapse}
/>

Header Component

The Shell automatically renders the <Header> component:

// Shell internally does:
<Header
  breadcrumbs={currentBreadcrumbs}
  user={currentUser}
/>

Best Practices

Keep Shell Minimal

The Shell should only contain layout logic, not business logic:

// Good
<Shell>
  <Dashboard />
</Shell>

// Bad - don't add complex logic to Shell
<Shell>
  {isLoading ? <Spinner /> : <Dashboard />}
</Shell>

Use View Components for Content

Wrap content in semantic View components:

// Good
<Shell>
  <DashboardView>
    <MetricsPanel />
    <ChartPanel />
  </DashboardView>
</Shell>

// Bad - don't put raw content in Shell
<Shell>
  <div>
    <h1>Dashboard</h1>
    <p>Metrics...</p>
  </div>
</Shell>

Handle Mobile Navigation

Ensure navigation works on mobile:

<Shell>
  {/* Shell handles mobile drawer automatically */}
  <Dashboard />
</Shell>

Accessibility

The Shell component implements several accessibility features:

  • Landmark regions - <nav>, <header>, <main>
  • Skip links - Jump to main content
  • Keyboard navigation - Focus management
  • Screen reader labels - Descriptive ARIA labels
<div role="application">
  <a href="#main" class="skip-link">Skip to content</a>
  <header role="banner">
    <!-- Header content -->
  </header>
  <nav role="navigation" aria-label="Main navigation">
    <!-- Sidebar navigation -->
  </nav>
  <main id="main" role="main">
    <!-- Main content -->
  </main>
</div>

On this page