mdxui

Header

Top header bar component with breadcrumbs and user menu

Header

The Header component provides the top navigation bar for authenticated applications. It displays breadcrumbs, search, notifications, and user menu.

Type Signature

interface AppHeaderProps {
  /** Current user */
  user?: {
    name: string
    email: string
    avatar?: string
  }
  /** Show search */
  showSearch?: boolean
  /** Show notifications */
  showNotifications?: boolean
  /** Breadcrumbs */
  breadcrumbs?: Array<{
    label: string
    href?: string
  }>
}

Usage

<Header
  user={{
    name: 'John Doe',
    email: 'john@acme.com',
    avatar: 'https://...'
  }}
  breadcrumbs={[
    { label: 'Dashboard', href: '/' },
    { label: 'Projects', href: '/projects' },
    { label: 'Acme Website' },
  ]}
/>

Props

user

Current user information displayed in the user menu.

<Header
  user={{
    name: 'John Doe',
    email: 'john@acme.com',
    avatar: 'https://avatar.example.com/john.jpg'
  }}
/>

Without avatar:

<Header
  user={{
    name: 'John Doe',
    email: 'john@acme.com'
    // Fallback to initials (JD)
  }}
/>

showSearch

Controls whether the search box is displayed. Defaults to true.

// Show search (default)
<Header showSearch={true} />

// Hide search
<Header showSearch={false} />

showNotifications

Controls whether the notifications bell is displayed. Defaults to true.

// Show notifications (default)
<Header showNotifications={true} />

// Hide notifications
<Header showNotifications={false} />

Array of breadcrumb items showing the current location.

<Header
  breadcrumbs={[
    { label: 'Dashboard', href: '/' },
    { label: 'Projects', href: '/projects' },
    { label: 'Acme Website' },  // Current page (no href)
  ]}
/>

Layout Structure

The Header component has this structure:

┌──────────────────────────────────────────────────┐
│ Breadcrumbs    [Search]    🔔  👤               │
└──────────────────────────────────────────────────┘

With All Features

┌──────────────────────────────────────────────────┐
│ Home > Projects > Acme    [Search]  🔔  👤 John │
└──────────────────────────────────────────────────┘

Minimal (No Search/Notifications)

┌──────────────────────────────────────────────────┐
│ Home > Projects > Acme                  👤 John │
└──────────────────────────────────────────────────┘

Without Breadcrumbs

┌──────────────────────────────────────────────────┐
│                    [Search]    🔔  👤 John      │
└──────────────────────────────────────────────────┘

Breadcrumbs show the current location in the app hierarchy.

Simple Path

<Header
  breadcrumbs={[
    { label: 'Dashboard', href: '/' },
    { label: 'Settings' },
  ]}
/>

Renders: Dashboard > Settings

Deep Path

<Header
  breadcrumbs={[
    { label: 'Dashboard', href: '/' },
    { label: 'Projects', href: '/projects' },
    { label: 'Acme Website', href: '/projects/acme' },
    { label: 'Settings' },
  ]}
/>

Renders: Dashboard > Projects > Acme Website > Settings

Dynamic Breadcrumbs

Breadcrumbs typically update based on the current route:

function useCurrentBreadcrumbs() {
  const pathname = usePathname()

  if (pathname === '/') {
    return [{ label: 'Dashboard' }]
  }

  if (pathname === '/projects') {
    return [
      { label: 'Dashboard', href: '/' },
      { label: 'Projects' },
    ]
  }

  if (pathname.startsWith('/projects/')) {
    const projectId = pathname.split('/')[2]
    return [
      { label: 'Dashboard', href: '/' },
      { label: 'Projects', href: '/projects' },
      { label: getProjectName(projectId) },
    ]
  }

  return []
}

<Header breadcrumbs={useCurrentBreadcrumbs()} />

The search box triggers the global search palette.

Search Trigger

Clicking the search box opens a command palette:

┌────────────────────────────┐
│ 🔍 Search...          ⌘K  │
└────────────────────────────┘

Search Palette

┌─────────────────────────────────────┐
│ 🔍 Search or type a command...     │
├─────────────────────────────────────┤
│ 📄 Projects                         │
│ 👥 Team Members                     │
│ ⚙  Settings                        │
│ 📁 Recent Files                     │
├─────────────────────────────────────┤
│ Quick Actions                       │
│ ➕ New Project                      │
│ 👤 Invite Team Member               │
└─────────────────────────────────────┘

Keyboard Shortcut

The search box shows the keyboard shortcut:

  • macOS: ⌘K
  • Windows/Linux: Ctrl+K

Notifications

The notifications bell shows unread count and opens a notification panel.

Notification Bell

🔔     No unread
🔔 3   3 unread notifications

Notification Panel

┌─────────────────────────────────────┐
│ Notifications              Mark all │
├─────────────────────────────────────┤
│ 🔵 New API key created              │
│    2 minutes ago                    │
│                                     │
│ ⚪ Webhook failed                   │
│    1 hour ago                       │
│                                     │
│ ⚪ New team member joined           │
│    3 hours ago                      │
├─────────────────────────────────────┤
│ View all notifications              │
└─────────────────────────────────────┘

Notification Types

IconTypeExample
🔵UnreadNew event
⚪ReadViewed event
✅SuccessAction completed
⚠️WarningLimit approaching
❌ErrorAction failed
📢AnnouncementNew feature
👤User actionTeam invite

User Menu

The user menu displays user info and account actions.

User Avatar

Shows user avatar or initials:

┌────┐
│ JD │  John Doe (initials)
└────┘

┌────┐
│ 📷 │  John Doe (avatar)
└────┘

User Dropdown

┌─────────────────────────────┐
│ 👤 John Doe                 │
│    john@acme.com            │
├─────────────────────────────┤
│ Profile                     │
│ Settings                    │
│ Billing                     │
│ Documentation               │
│ Support                     │
├─────────────────────────────┤
│ Sign Out                    │
└─────────────────────────────┘

Common actions in the user menu:

  • Profile - View/edit profile
  • Settings - Account settings
  • Billing - Subscription & billing
  • Team - Team management (multi-tenant)
  • Workspace - Switch workspace (multi-tenant)
  • Documentation - Help docs
  • Support - Contact support
  • Changelog - What's new
  • API Keys - Developer tools
  • Sign Out - Log out

Responsive Behavior

Desktop (≥1024px)

Full header with all features:

┌──────────────────────────────────────────────────┐
│ Home > Projects > Acme    [Search]  🔔  👤 John │
└──────────────────────────────────────────────────┘

Tablet (768px - 1023px)

Condensed breadcrumbs:

┌──────────────────────────────────────────────────┐
│ ... > Acme        [Search]  🔔  👤              │
└──────────────────────────────────────────────────┘

Mobile (under 768px)

Minimal header with hamburger menu:

┌──────────────────────────────────────────────────┐
│ ☰  Acme                           🔔  👤        │
└──────────────────────────────────────────────────┘

On mobile:

  • Hamburger menu (☰) toggles sidebar
  • Breadcrumbs show only current page
  • Search accessed via icon
  • User menu opens bottom sheet

Common Patterns

Standard Header

Most applications use all features:

<Header
  user={currentUser}
  breadcrumbs={currentBreadcrumbs}
  showSearch={true}
  showNotifications={true}
/>

Minimal Header

For focused views (editor, canvas):

<Header
  user={currentUser}
  showSearch={false}
  showNotifications={false}
/>

Public Header

For authenticated but public-facing views:

<Header
  user={currentUser}
  breadcrumbs={[{ label: 'Documentation' }]}
  showNotifications={false}
/>

Integration with Shell

The Header is automatically rendered by the Shell:

<Shell>
  {/* Shell internally renders: */}
  <Header
    user={currentUser}
    breadcrumbs={currentBreadcrumbs}
  />
  <Sidebar nav={navigation} />
  <main>{children}</main>
</Shell>

Customization

Custom Styles

<Header
  className="border-b-2 border-blue-500"
  user={currentUser}
/>

Custom Height

<Header
  className="h-16"  // Default is h-14
  user={currentUser}
/>

Custom Actions

Add custom actions to the header:

<Header
  user={currentUser}
  actions={
    <>
      <Button variant="outline">Export</Button>
      <Button>Create Project</Button>
    </>
  }
/>

App-Specific Headers

Different app types may customize the header:

Developer App

<Header
  breadcrumbs={[
    { label: 'Overview', href: '/' },
    { label: 'API Keys' },
  ]}
  actions={
    <Button>Create API Key</Button>
  }
/>

Admin App

<Header
  breadcrumbs={[
    { label: 'Collections', href: '/collections' },
    { label: 'Posts', href: '/posts' },
    { label: 'Edit Post' },
  ]}
  actions={
    <>
      <Button variant="outline">Preview</Button>
      <Button>Publish</Button>
    </>
  }
/>

CRM App

<Header
  breadcrumbs={[
    { label: 'Contacts', href: '/contacts' },
    { label: 'Acme Corp' },
  ]}
  actions={
    <>
      <Button variant="outline">Add Note</Button>
      <Button>Create Deal</Button>
    </>
  }
/>

Accessibility

The Header implements accessibility features:

  • Landmark region - Uses <header role="banner">
  • Navigation - Breadcrumbs use <nav aria-label="Breadcrumb">
  • Keyboard navigation - All controls are keyboard accessible
  • Focus management - Visible focus indicators
  • Screen reader labels - Descriptive ARIA labels
<header role="banner">
  <nav aria-label="Breadcrumb">
    <ol>
      <li><a href="/">Dashboard</a></li>
      <li><a href="/projects">Projects</a></li>
      <li aria-current="page">Acme Website</li>
    </ol>
  </nav>

  <button aria-label="Search" aria-keyshortcuts="Control+K">
    Search
  </button>

  <button aria-label="Notifications" aria-describedby="notification-count">
    <span id="notification-count">3 unread notifications</span>
  </button>

  <button aria-label="User menu" aria-expanded="false">
    <img alt="John Doe" src="..." />
  </button>
</header>

Best Practices

Keep Breadcrumbs Shallow

Limit breadcrumb depth to 3-4 levels:

// Good - 3 levels
<Header
  breadcrumbs={[
    { label: 'Dashboard', href: '/' },
    { label: 'Projects', href: '/projects' },
    { label: 'Acme Website' },
  ]}
/>

// Bad - too deep
<Header
  breadcrumbs={[
    { label: 'Dashboard', href: '/' },
    { label: 'Workspace', href: '/workspace' },
    { label: 'Projects', href: '/projects' },
    { label: 'Category', href: '/projects/category' },
    { label: 'Subcategory', href: '/projects/category/sub' },
    { label: 'Acme Website' },
  ]}
/>

Use Consistent User Menu

Maintain consistent menu items across the app:

// Good - consistent actions
const userMenu = [
  'Profile',
  'Settings',
  'Billing',
  'Documentation',
  'Support',
  '---',  // Separator
  'Sign Out',
]

// Bad - inconsistent
const userMenu = [
  'My Account',   // Use "Profile"
  'Preferences',  // Use "Settings"
  'Logout',       // Use "Sign Out"
]

Handle Long Breadcrumbs

Truncate long breadcrumb labels:

// Good - truncated
<Header
  breadcrumbs={[
    { label: 'Projects', href: '/projects' },
    { label: 'Very Long Project Name That Would...' },
  ]}
/>

// Bad - too long
<Header
  breadcrumbs={[
    { label: 'Projects', href: '/projects' },
    { label: 'Very Long Project Name That Would Overflow The Header' },
  ]}
/>
  • Shell - App shell layout
  • Sidebar - Navigation sidebar
  • App - Root application wrapper

On this page