Navigation Configuration

Configure sidebar navigation items

Type Definition

interface NavItem {
  /**
   * Title (can be i18n key or plain text)
   */
  title: string;

  /**
   * Route path
   */
  path: string;

  /**
   * Icon component (Lucide icon or custom component)
   */
  icon: LucideIcon | ComponentType<{ className?: string }>;

  /**
   * Badge content (optional)
   */
  badge?: string | number;
}

Basic Configuration

import { Home, Settings, Users, FileText } from 'lucide-react';

nav: [
  { title: 'Home', path: '/', icon: Home },
  { title: 'Users', path: '/users', icon: Users },
  { title: 'Documents', path: '/documents', icon: FileText },
  { title: 'Settings', path: '/settings', icon: Settings },
],

Using i18n Keys

nav: [
  { title: 'app.home', path: '/', icon: Home },
  { title: 'app.users', path: '/users', icon: Users },
  { title: 'settings.title', path: '/settings', icon: Settings },
],

i18n: {
  resources: {
    en: {
      app: {
        home: 'Home',
        users: 'Users',
      },
      settings: {
        title: 'Settings',
      },
    },
    zh: {
      app: {
        home: '首页',
        users: '用户',
      },
      settings: {
        title: '设置',
      },
    },
  },
},

Adding Badges

Badges can display numbers or text:

nav: [
  { title: 'Inbox', path: '/inbox', icon: Inbox, badge: 5 },
  { title: 'Updates', path: '/updates', icon: Bell, badge: 'New' },
  { title: 'Settings', path: '/settings', icon: Settings },
],

Custom Icons

Besides Lucide icons, you can also use custom components:

// src/components/icons/CustomIcon.tsx
export function CustomIcon({ className }: { className?: string }) {
  return (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor">
      <circle cx="12" cy="12" r="10" />
    </svg>
  );
}
import { CustomIcon } from './components/icons/CustomIcon';

nav: [
  { title: 'Custom', path: '/custom', icon: CustomIcon },
],

Route Mapping

The navigation item's path should match routes defined in App.tsx:

// src/App.tsx
<Routes>
  <Route element={<Shell />}>
    <Route path="/" element={<Home />} />
    <Route path="/users" element={<Users />} />
    <Route path="/documents" element={<Documents />} />
    <Route path="/settings" element={<Settings />} />
  </Route>
</Routes>
// src/config.ts
nav: [
  { title: 'Home', path: '/', icon: Home },
  { title: 'Users', path: '/users', icon: Users },
  { title: 'Documents', path: '/documents', icon: FileText },
  { title: 'Settings', path: '/settings', icon: Settings },
],

Active State

Navigation items are automatically highlighted based on the current route. Matching rules:

  • Exact match takes priority
  • If no exact match, the longest prefix is matched

For example, when the current route is /users/123:

  • /users will be highlighted
  • / will not be highlighted

Custom NavItem Component

If you need to fully customize the rendering of navigation items, you can override the NavItem component:

import type { NavItemComponentProps } from '@linch-tech/desktop-core';

function CustomNavItem({ item, isActive, onClick }: NavItemComponentProps) {
  const Icon = item.icon;

  return (
    <button
      onClick={onClick}
      className={`flex items-center gap-2 px-3 py-2 rounded ${
        isActive ? 'bg-primary text-white' : 'hover:bg-muted'
      }`}
    >
      <Icon className="w-4 h-4" />
      <span>{item.title}</span>
      {item.badge && (
        <span className="ml-auto bg-red-500 text-white text-xs px-1.5 rounded-full">
          {item.badge}
        </span>
      )}
    </button>
  );
}

// Use in configuration
components: {
  NavItem: CustomNavItem,
},

Complete Example

import { Home, Users, FileText, Settings, Inbox, Bell } from 'lucide-react';

export const config = {
  nav: [
    { title: 'app.home', path: '/', icon: Home },
    { title: 'app.inbox', path: '/inbox', icon: Inbox, badge: 3 },
    { title: 'app.users', path: '/users', icon: Users },
    { title: 'app.documents', path: '/documents', icon: FileText },
    { title: 'app.notifications', path: '/notifications', icon: Bell, badge: 'New' },
    { title: 'settings.title', path: '/settings', icon: Settings },
  ],

  i18n: {
    resources: {
      en: {
        app: {
          home: 'Home',
          inbox: 'Inbox',
          users: 'Users',
          documents: 'Documents',
          notifications: 'Notifications',
        },
        settings: {
          title: 'Settings',
        },
      },
      zh: {
        app: {
          home: '首页',
          inbox: '收件箱',
          users: '用户',
          documents: '文档',
          notifications: '通知',
        },
        settings: {
          title: '设置',
        },
      },
    },
  },
};