---
title: "Layout System"
description: "The Layout System provides a standardized, compositional framework for structuring documentation sites. It addresses the common challenge of fragmented UI components by offering unified primitives ..."
last_updated: "2026-07-02T09:46:39.397774+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/rendering-ui/layout-system"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/radix-ui/src/layouts/notebook/slots/sidebar.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/notebook/slots/sidebar.tsx)
- [packages/base-ui/src/layouts/notebook/slots/sidebar.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/slots/sidebar.tsx)
- [packages/base-ui/src/components/sidebar/base.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/base.tsx)
- [packages/base-ui/src/layouts/flux/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/flux/index.tsx)
- [packages/radix-ui/src/layouts/flux/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/flux/index.tsx)
- [packages/base-ui/src/layouts/notebook/client.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/client.tsx)
- [packages/radix-ui/src/layouts/notebook/client.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/notebook/client.tsx)
- [packages/base-ui/src/layouts/shared/client.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/shared/client.tsx)
- [packages/radix-ui/src/layouts/shared/client.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/shared/client.tsx)
- [packages/radix-ui/src/legacy/layout.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/legacy/layout.tsx)
- [packages/base-ui/src/layouts/notebook/slots/container.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/slots/container.tsx)
- [packages/radix-ui/src/layouts/notebook/slots/container.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/notebook/slots/container.tsx)
- [packages/core/src/framework/waku.tsx](https://github.com/blade47/fumadocs/blob/main/packages/core/src/framework/waku.tsx)
- [packages/base-ui/src/layouts/notebook/slots/header.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/slots/header.tsx)
- [packages/radix-ui/src/layouts/notebook/slots/header.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/notebook/slots/header.tsx)
- [packages/base-ui/src/layouts/home/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/home/index.tsx)
- [packages/radix-ui/src/layouts/home/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/home/index.tsx)
- [packages/base-ui/src/layouts/notebook/page/slots/container.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/page/slots/container.tsx)
- [packages/base-ui/src/layouts/notebook/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/index.tsx)
- [packages/radix-ui/src/layouts/notebook/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/notebook/index.tsx)
- [packages/radix-ui/src/layouts/shared/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/shared/index.tsx)
- [packages/core/src/framework/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/core/src/framework/index.tsx)
- [packages/base-ui/src/layouts/flux/page/slots/container.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/flux/page/slots/container.tsx)
- [packages/base-ui/src/layouts/flux/slots/sidebar.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/flux/slots/sidebar.tsx)
- [packages/core/src/framework/tanstack.tsx](https://github.com/blade47/fumadocs/blob/main/packages/core/src/framework/tanstack.tsx)
- [packages/base-ui/src/layouts/shared/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/shared/index.tsx)
- [packages/base-ui/src/provider/waku.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/provider/waku.tsx)
- [packages/radix-ui/src/provider/waku.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/provider/waku.tsx)
- [packages/base-ui/src/provider/tanstack.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/provider/tanstack.tsx)
- [packages/core/src/framework/next.tsx](https://github.com/blade47/fumadocs/blob/main/packages/core/src/framework/next.tsx)
</details>

The Layout System provides a standardized, compositional framework for structuring documentation sites. It addresses the common challenge of fragmented UI components by offering unified primitives for sidebars, headers, and content areas, ensuring consistent navigation and layout behavior across different documentation styles (Notebook and Flux).

At its core, the system utilizes a hierarchical layout strategy driven by shared context providers. These providers encapsulate cross-cutting concerns like navigation states, theme switching, and language selection, allowing individual layout components to remain decoupled from the specific configuration of the host application.

By separating the "slots" (extensible areas of the UI) from the underlying implementation logic, the system allows for modular customization. Whether using the sophisticated "Notebook" style—focused on hierarchical content trees—or the more modern, interactive "Flux" style, developers interact with a predictable interface to inject custom branding, toolsets, and page content.

## Sidebar Architecture and State Management

The Sidebar subsystem acts as the primary navigation engine. It is built upon a `SidebarProvider` that manages open/collapsed states and responsive transitions (drawer vs. full mode). The sidebar logic is defined in `packages/base-ui/src/components/sidebar/base.tsx`, which serves as the foundation for both Notebook and Radix-UI layout variants.

The system uses a `FolderContext` to track hierarchy depth and collapsible states recursively. This ensures that tree-based navigation correctly handles indentation and trigger behavior.

```mermaid
flowchart TD
    A[SidebarProvider] --> B[SidebarContext]
    B --> C[SidebarContent]
    C --> D[SidebarViewport]
    D --> E[PageTreeRenderer]
    E --> F[SidebarFolder]
    F --> G[FolderContext]
    G --> H[SidebarItem]
```
Sources: [packages/base-ui/src/components/sidebar/base.tsx:75-112](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/base.tsx#L75-L112), [packages/base-ui/src/components/sidebar/base.tsx:298-305](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/base.tsx#L298-L305)

> [!TIP]
> The sidebar uses a `timerRef` in `SidebarContent` to handle hover states on collapsed sidebars. If the mouse leaves the viewport, it triggers a 500ms delay before closing, improving usability on desktop.

Sources: [packages/base-ui/src/components/sidebar/base.tsx:146-179](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/base.tsx#L146-L179)

## The Notebook Layout Mechanism

The Notebook layout implementation defines a rigid grid structure to manage the documentation lifecycle. It relies on `LayoutBody` (in `client.tsx`) to initialize the `LayoutContext`, which bundles navigational items, header/sidebar slots, and scroll-transparency logic.

The grid layout is computed dynamically in the `Container` component:

1.  Calculates `pageCol` based on layout width and sidebar/TOC column widths.
2.  Sets grid areas: `sidebar`, `header`, `main`, and `toc`.
3.  Injects CSS variables (`--fd-sidebar-col`, etc.) that control the layout responsiveness.

```mermaid
sequenceDiagram
    participant User
    participant LayoutBody
    participant LayoutContext
    participant Container
    User->>LayoutBody: Initialize DocsLayout
    LayoutBody->>LayoutContext: Provide (slots, navItems, props)
    LayoutBody->>Container: Render container
    Container->>Container: Calculate grid-template-columns
    Container-->>User: Render document body
```
Sources: [packages/base-ui/src/layouts/notebook/client.tsx:67-124](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/client.tsx#L67-L124), [packages/base-ui/src/layouts/notebook/slots/container.tsx:24-54](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/slots/container.tsx#L24-L54)

## Link Item Resolution

Link items are the building blocks of navigation. They are resolved via `resolveLinkItems` in `packages/base-ui/src/layouts/shared/index.tsx`. The system supports multiple types, filtering them by their `on` property ('menu', 'nav', 'all') to ensure they appear only where intended.

| Item Type | Key Properties | Purpose |
| :--- | :--- | :--- |
| `MainItemType` | `url`, `text`, `description` | Primary navigation links. |
| `IconItemType` | `url`, `icon`, `label` | Social/external links. |
| `ButtonItemType` | `url`, `icon`, `text` | Action-oriented navigation. |
| `MenuItemType` | `items`, `text` | Nested dropdown menus. |
| `CustomItemType` | `children` | Allows arbitrary UI injection. |

Sources: [packages/base-ui/src/layouts/shared/index.tsx:256-277](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/shared/index.tsx#L256-L277)

## Navigation Transparency and Scroll

The Notebook layout includes a transparency feature for navigation, enabled by the `transparentMode` option ('top', 'always', or 'none'). When 'top' is selected, it uses the `useIsScrollTop` hook to toggle the transparency state as the user scrolls.

> [!NOTE]
> `isNavTransparent` is passed via `LayoutContext` to the `Header` component, which applies a `data-transparent` attribute to its container. This allows CSS to reactively change background opacity based on scroll state.

Sources: [packages/base-ui/src/layouts/notebook/client.tsx:82-83](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/client.tsx#L82-L83), [packages/base-ui/src/layouts/notebook/slots/header.tsx:38-41](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/slots/header.tsx#L38-L41)

## Flux Layout Strategy

The Flux layout differs from the Notebook layout by prioritizing a mobile-first, floating navigation panel. It uses a custom `NavigationPanel` component that persists at the bottom of the screen on mobile or becomes a fixed floating element on larger screens via CSS grid or flexbox manipulation.

The Flux layout context provider also exposes `slots` for search triggers and layout tabs, but centers its interaction pattern around the `NavigationPanel` component, which manages search modal states and navigation toolsets.

Sources: [packages/base-ui/src/layouts/flux/index.tsx:62-76](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/flux/index.tsx#L62-L76)

## Framework Integration

The system supports multiple frameworks (Next.js, Waku, Tanstack) via the `FrameworkProvider` pattern. This decouples layout logic from the framework-specific router (e.g., `usePathname`, `push`).

| Design Choice | Benefit | Cost |
| :--- | :--- | :--- |
| FrameworkProvider | Agnostic router and link components. | Adds indirection to core UI components. |
| Slot Pattern | Allows extreme extensibility in headers/sidebars. | Requires consistent API surface across slots. |
| Grid-based Layout | Precise control over complex responsive areas. | Requires careful management of CSS grid template strings. |

Sources: [packages/core/src/framework/index.tsx:53-73](https://github.com/blade47/fumadocs/blob/main/packages/core/src/framework/index.tsx#L53-L73)

### Full Example: Configuring a Custom Header Slot

To customize the header behavior in a Notebook layout, one can inject a custom component using the `slots` prop provided by the `DocsLayout`.

```typescript
import { DocsLayout } from 'fumadocs-ui/layouts/notebook';

// Custom header implementation
const CustomHeader = () => (
  <header className="custom-header">
    <h1>My Docs</h1>
  </header>
);

export default function RootLayout({ children }) {
  return (
    <DocsLayout
      tree={tree}
      slots={{
        header: CustomHeader,
      }}
    >
      {children}
    </DocsLayout>
  );
}
```
Sources: [packages/base-ui/src/layouts/notebook/index.tsx:11-21](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/notebook/index.tsx#L11-L21)

## Related

- [Sidebar Navigation](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/rendering-ui/sidebar-navigation)
- [Table of Contents](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/rendering-ui/table-of-contents)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/llms.txt) for all pages in this wiki.
