Features

  • Hamburger button that opens a left-sliding panel
  • Collapsible category sections for organising many navigation items
  • Single-item categories render as direct links (e.g., Home)
  • Multi-item categories expand/collapse with chevron indicators
  • Active page highlighting with blue accent and indicator dot
  • Auto-expands the category containing the active page
  • Smooth staggered animations for menu items
  • Backdrop overlay when panel is open
  • Keyboard accessible (Tab navigation, Escape to close, focus trap)
  • Sticky positioning with backdrop blur
  • Optional Clerk authentication UI integration

Interactive Demo

Click the hamburger menu (☰) in the top-left corner to see the navbar in action. The current navbar you're using is the component! Try expanding different categories and navigating between pages.

Usage (Categorised Navigation)

<script lang="ts">
  import Navbar from '$lib/components/Navbar.svelte';
  import type { MenuCategory } from '$lib/types';

  const menuCategories: MenuCategory[] = [
    {
      name: 'Home',
      icon: '🏠',
      items: [{ label: 'Home', href: '/', icon: '🏠', active: true }]
    },
    {
      name: 'Components',
      icon: '🧩',
      items: [
        { label: 'CardStack', href: '/cardstack', icon: 'πŸƒ', active: false },
        { label: 'MagicCard', href: '/magiccard', icon: '✨', active: false }
      ]
    }
  ];
</script>

<Navbar {menuCategories} currentPageTitle="Home" />

Props

PropTypeDefaultDescription
menuCategoriesMenuCategory[][]Categorised navigation items (recommended)
menuItemsMenuItem[][]Legacy flat menu items (for backwards compatibility)
currentPageTitlestring'Home'Title of the current page (for accessibility)
logoIconstring'⚑'Logo icon or emoji
logoTextstring'Svelte Templates'Logo text displayed next to icon
logoHrefstring'/'URL the logo links to
isClerkConfiguredbooleanfalseShow Clerk auth UI (SignIn/UserButton) or demo badge

Type Definitions

// Categorised navigation (recommended)
interface MenuCategory {
  name: string;       // Category display name
  icon?: string;      // Optional category icon/emoji
  items: MenuItem[];  // Items in this category
}

// Individual menu item
interface MenuItem {
  label: string;      // Display text
  href: string;       // Link URL
  icon?: string;      // Optional icon/emoji
  active?: boolean;   // Whether this is the active page
}

Category Behaviour

  • Single-item categories: Render as direct links without expand/collapse (e.g., Home)
  • Multi-item categories: Show a collapsible header with chevron; click to expand/collapse
  • Auto-expand: The category containing the active page automatically expands on load
  • Active highlighting: Active items show blue text and a small indicator dot

Implementation Notes

  • Panel Scrolling: The panel automatically becomes scrollable if menu items exceed viewport height
  • Body Scroll Lock: When panel is open, body scrolling is prevented (coordinated with other components via scrollLock utility)
  • Close Triggers: Panel closes when clicking a menu item, clicking overlay, or pressing Escape
  • Focus Trap: Tab navigation stays within the panel when open (WCAG 2.4.3)
  • Responsive: Panel width adapts based on screen size (280px mobile, 320px tablet+)
  • Accessibility: ARIA labels, expanded states, focus management, and reduced motion support

Clerk Integration

When isClerkConfigured is true, the navbar displays Clerk's authentication UI in the right section:

  • Signed out: Shows a "Sign in" button
  • Signed in: Shows the UserButton avatar with dropdown menu
  • Not configured: Shows a "Demo Mode" badge

Copy the Component

This component is self-contained and can be copied directly into your project. You'll need:

  • src/lib/components/Navbar.svelte - The component file
  • src/lib/types.ts - MenuCategory, MenuItem, and NavbarProps interfaces
  • src/lib/scrollLock.ts - Scroll lock utility (optional, for coordination)
  • svelte-clerk - Only if using Clerk auth integration