Components

Application Menu

The Application Menu (sidebar) provides configurable navigation for your application. It supports teams, modules, page groups, and role-based visibility.

Overview

The Application Menu is configured using ServerTeam objects that define:

  • Teams (top-level navigation sections)
  • Modules (groupings within teams)
  • Page Groups (sections within modules)
  • Pages (individual navigation items)

ServerTeam Structure

// src/components/sidebar/modules/work.ts
import type { ServerTeam } from '@wayvo-ai/core/ui';

export const workPortal: ServerTeam = {
  name: '@Work',
  logo: 'MiniLogo',
  teamPath: '/work',
  menuTitle: '@Work Portal',
  modules: [
    {
      title: '@Work',
      modulePath: '/work',
      pageGroups: [
        {
          title: 'Configuration',
          groupPath: '/config',
          icon: 'Settings2',
          pages: [
            {
              title: 'Customers',
              pagePath: '/customers',
              icon: 'Building2',
              roles: ['admin'],
              hidden: false,
            },
            {
              title: 'Projects',
              pagePath: '/projects',
              icon: 'Briefcase',
              roles: ['admin'],
              hidden: false,
            },
          ],
        },
        {
          title: 'Reports',
          groupPath: '/reports',
          icon: 'BarChart3',
          pages: [
            {
              title: 'Timesheet Lines',
              pagePath: '/timesheet-lines',
              icon: 'FileText',
              roles: ['all_users'],
            },
          ],
        },
      ],
    },
  ],
};

Registering Teams

// src/lib/server/sidebar/index.ts
import { workPortal } from '@/components/sidebar/modules/work';
import { vendorPortal } from '@/components/sidebar/modules/vm';

export const SIDEBAR_TEAMS: ServerTeam[] = [
  workPortal,
  vendorPortal,
];

Page Properties

PropertyTypeDescription
titlestringDisplay name
pagePathstringRoute path
iconstringLucide icon name
rolesstring[]Required roles (empty = all users)
hiddenbooleanHide from menu

Active State Detection

The sidebar automatically highlights the active page based on the current route. You can customize this behavior:

// src/components/sidebar/actions.ts
export function isSidebarItemActive(pathname: string, item: PageItem, team: Team): boolean {
  // Custom logic for active state
  return pathname.startsWith(item.pagePath);
}

Dynamic Sidebar Content

Add custom content below the navigation:

// src/components/sidebar/app-sidebar-content.tsx
'use client';

import { ChatProvider, SidebarHistory } from '@wayvo-ai/core/ui';
import type { Team } from '@wayvo-ai/core/ui';

export function AppSidebarContent({ activeTeam }: { activeTeam: Team }) {
  return (
    activeTeam &&
    activeTeam.teamPath === '/chat' && (
      <ChatProvider api="/api/chat" source="chat">
        <SidebarHistory />
      </ChatProvider>
    )
  );
}

Icons

Use Lucide React icon names:

{
  icon: 'Settings2',      // Settings icon
  icon: 'Building2',      // Building icon
  icon: 'Briefcase',     // Briefcase icon
  icon: 'BarChart3',     // Chart icon
  icon: 'FileText',      // File icon
}

Role-Based Visibility

Pages are automatically hidden based on user roles:

{
  title: 'Admin Settings',
  pagePath: '/admin/settings',
  roles: ['admin'],  // Only visible to admins
}

{
  title: 'Public Page',
  pagePath: '/public',
  roles: [],  // Visible to all authenticated users
}

Next Steps

Previous
Tables
Next
Forms