---
title: "App shell"
description: "The frame every dashboard page shares: a skip link, a sidebar that folds into an icon rail from lg and becomes a drawer on phones, a header for breadcrumbs and actions, and the page in a scrolling main landmark."
---

> Documentation Index
> Fetch the complete documentation index at: https://epidermis.getarbol.com/llms.txt
> Use this file to discover all available pages before exploring further.

# App shell

## Dashboard frame

Fold the sidebar with the header’s button; on the rail, entries name themselves in a tooltip, Billing shows its pages beside its icon, and the organization and account menus show their pictures alone. The other apps open in a new tab. Below lg the menu button opens the drawer.

```tsx
import { ChatsIcon, GearSixIcon, HourglassIcon, MagnifyingGlassIcon, MegaphoneIcon, ReceiptIcon, RobotIcon, SquaresFourIcon, UserCircleIcon, UsersIcon, UsersThreeIcon } from '@phosphor-icons/react';
import { useState } from 'react';
import { AccountMenu, AppShell, Button, ColorSchemeSubmenu, LanguageSubmenu, MenuItem, MenuSeparator, OrganizationMenu, PageContainer, PageDescription, PageHeader, PageTitle, productIcon } from '@arbol-ai/ui';
import type { ColorScheme, NavigationGroup } from '@arbol-ai/ui';

const NAVIGATION: NavigationGroup[] = [
  {
    items: [
      { label: 'Overview', href: '#/app-shell', icon: SquaresFourIcon },
      { label: 'Conversations', href: '#/app-shell/conversations', icon: ChatsIcon },
      { label: 'Contacts', href: '#/app-shell/contacts', icon: UsersIcon },
      { label: 'Agents', href: '#/app-shell/agents', icon: RobotIcon },
      { label: 'Campaigns', href: '#/app-shell/campaigns', icon: MegaphoneIcon },
      { label: 'Waiting list', href: '#/app-shell/waitlist', icon: HourglassIcon, badge: 3 },
    ],
  },
  {
    label: 'Administration',
    items: [
      { label: 'Team', href: '#/app-shell/team', icon: UsersThreeIcon },
      {
        label: 'Billing',
        href: '#/app-shell/billing',
        icon: ReceiptIcon,
        pages: [
          { label: 'Summary', href: '#/app-shell/billing' },
          { label: 'Invoices', href: '#/app-shell/billing/invoices' },
        ],
      },
    ],
  },
  {
    label: 'Applications',
    items: [
      { label: 'Agenda', href: 'https://agenda.example.com', icon: productIcon('agenda'), target: '_blank' },
      { label: 'Ámbar', href: 'https://ambar.example.com', icon: productIcon('ambar'), target: '_blank' },
    ],
  },
];

const LANGUAGES = [
  { label: 'English', value: 'en' },
  { label: 'Español', value: 'es' },
] as const;

const DashboardFrame = () => {
  const [isCollapsed, setIsCollapsed] = useState(false);
  const [colorScheme, setColorScheme] = useState<ColorScheme>('system');
  const [language, setLanguage] = useState<'en' | 'es'>('en');
  return (
    <AppShell
      accountMenu={
        <AccountMenu email="ana.ruiz@example.com" name="Ana Ruiz" onSignOut={() => undefined}>
          <MenuItem href="#/app-shell/profile" icon={<UserCircleIcon />}>
            Profile
          </MenuItem>
          <MenuSeparator />
          <ColorSchemeSubmenu onChange={setColorScheme} value={colorScheme} />
          <LanguageSubmenu onChange={setLanguage} options={LANGUAGES} value={language} />
        </AccountMenu>
      }
      className="rounded-card h-[520px] overflow-hidden border"
      currentPath="#/app-shell/contacts"
      header={<span className="truncate text-sm">Contacts</span>}
      headerActions={
        <Button aria-label="Search" size="icon" variant="ghost">
          <MagnifyingGlassIcon aria-hidden />
        </Button>
      }
      isCollapsed={isCollapsed}
      navigation={NAVIGATION}
      onCollapsedChange={setIsCollapsed}
      organizationSwitcher={
        <OrganizationMenu name="Clínica Norte" onSwitch={() => undefined}>
          <MenuItem href="#/app-shell/settings" icon={<GearSixIcon />}>
            Settings
          </MenuItem>
        </OrganizationMenu>
      }
      secondaryNavigation={[{ label: 'Settings', href: '#/app-shell/settings', icon: GearSixIcon }]}
    >
      <PageContainer>
        <PageHeader>
          <div>
            <PageTitle>Contacts</PageTitle>
            <PageDescription>Everyone your agents talked to.</PageDescription>
          </div>
        </PageHeader>
      </PageContainer>
    </AppShell>
  );
};

<DashboardFrame />
```

## Source

The examples above are [`src/components/app-shell/app-shell.examples.tsx`](https://github.com/getarbol/project-arbol-ui/blob/main/src/components/app-shell/app-shell.examples.tsx), which the library's tests render too.

Source: https://epidermis.getarbol.com/components/layout/app-shell/index.mdx
