---
title: Shell
description: The frame of an application page, a sidebar next to the main content.
---

```tsx
import { Shell, Sidebar } from "@openperf/deft";

import { Preview } from "../../src/Preview";

export default function ShellBasic() {
  return (
    <Preview block={true}>
      <Shell.Root className="min-h-124">
        <Sidebar.Root className="h-124">
          <Sidebar.Content>
            <Sidebar.Item href="#item-1">Item 1</Sidebar.Item>
            <Sidebar.Item href="#item-2">Item 2</Sidebar.Item>
            <Sidebar.Item href="#item-3">Item 3</Sidebar.Item>
          </Sidebar.Content>
        </Sidebar.Root>
        <Shell.Main>
          <Shell.Bar />
          <p className="px-gutter py-5">Content</p>
        </Shell.Main>
      </Shell.Root>
    </Preview>
  );
}
```

- Use the shell for pages inside the application. `Shell.Root` lays out [Sidebar](/deft/components/sidebar) `Root` next to `Shell.Main`; the sidebar contents stay with the app.
- `Shell.Root` wraps `Sidebar.Provider`, so `Sidebar.Root` and every `Sidebar.Trigger` beneath it share open state. It is at least the height of the viewport and creates a stacking context for [Backdrop](/deft/components/backdrop).
- `Shell.Main` is the page's `main` region. Pass route-level classes, such as a view transition name, through `className`.
- `Shell.Bar` is a row with a `Sidebar.Trigger`, for pages that have no toolbar of their own, such as fallbacks and empty states. It takes no children and is hidden from the `md` breakpoint up. Pages with a toolbar or breadcrumb put `Sidebar.Trigger` inline instead.

## API

Parts: `Root`, `Bar`, `Main`. Other props go to the native element: `div` for `Root` and `Bar`, `main` for `Main`.
