---
title: "Sidebar Navigation"
description: "Sidebar navigation is a foundational subsystem that provides structural document hierarchy visualization and site navigation. It serves as the primary way for users to traverse complex documentatio..."
last_updated: "2026-07-02T09:46:39.721333+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/rendering-ui/sidebar-navigation"
---

<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/layouts/home/slots/header.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/home/slots/header.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/core/src/source/page-tree/builder.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/src/source/page-tree/builder.ts)
- [packages/radix-ui/src/components/sidebar/base.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/components/sidebar/base.tsx)
- [packages/radix-ui/src/components/sidebar/page-tree.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/components/sidebar/page-tree.tsx)
- [packages/radix-ui/src/components/sidebar/tabs/dropdown.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/components/sidebar/tabs/dropdown.tsx)
- [packages/radix-ui/src/layouts/flux/slots/sidebar.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/flux/slots/sidebar.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/radix-ui/src/components/sidebar/link-item.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/components/sidebar/link-item.tsx)
- [packages/radix-ui/src/utils/use-footer-items.ts](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/utils/use-footer-items.ts)
- [packages/base-ui/src/components/sidebar/page-tree.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/page-tree.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/base-ui/src/components/sidebar/tabs/dropdown.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/tabs/dropdown.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/home/slots/header.tsx](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/layouts/home/header.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/core/src/source/llms.ts](https://github.com/blade47/fumadocs/blob/main/packages/core/src/source/llms.ts)
- [packages/base-ui/src/components/sidebar/tabs/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/tabs/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/base-ui/src/components/sidebar/link-item.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/link-item.tsx)
- [packages/radix-ui/src/components/sidebar/tabs/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/sidebar/tabs/index.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/shared/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/layouts/shared/index.tsx)
</details>

Sidebar navigation is a foundational subsystem that provides structural document hierarchy visualization and site navigation. It serves as the primary way for users to traverse complex documentation content, bridging the gap between raw data structures (like page trees) and a functional UI. By decoupling data rendering (the tree) from structural UI concerns (collapsible folders, drawers, scroll tracking), the system enables developers to inject layout-specific components while maintaining consistent navigation logic.

The design embodies a clear separation between the logic of "being a sidebar"—handling provider state, media queries, and keyboard navigation—and the specific layout representation, such as the `notebook` layout, which supports desktop collapsing and mobile drawers. This hierarchy ensures that logic like `useFolderDepth` or `useSidebar` remains stable across different UI variations while allowing specific slots to render custom elements like tabs, footers, or banners.

Interaction with adjacent components is primarily driven by context providers (`SidebarProvider`) that manage shared state such as open/collapsed status and navigation hooks. The system also tightly integrates with document loading infrastructure, ensuring that the navigation automatically reflects the site's directory structure via the page-tree loader.

## The Sidebar Architecture

The sidebar subsystem is built as a set of decoupled functional components centered around `SidebarProvider`. The provider acts as the state arbiter for the entire navigation tree, managing whether the sidebar is in `drawer` or `full` mode based on media queries, and holding a ref to `closeOnRedirect` to prevent premature closure during site navigation.

```mermaid
flowchart TD
    A["SidebarProvider"] --> B["SidebarContent"]
    A --> C["SidebarDrawerContent"]
    B --> D["SidebarViewport"]
    D --> E["SidebarPageTree"]
    E --> F["SidebarFolder / 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)

## Sidebar State and Context

The subsystem uses React Context to share state across deeply nested nodes (like folder triggers or individual links). The state is split into `SidebarContext` and `FolderContext`.

*   **`SidebarContext`**: Manages the global sidebar lifecycle (drawer vs. full mode, global collapse status).
*   **`FolderContext`**: Tracks hierarchical concerns for collapsible items, including depth and trigger status.

> [!NOTE]
> The `useSidebar` hook provides `closeOnRedirect`, a `RefObject` allowing components to inhibit the standard sidebar closure behavior during a page transition. Setting `closeOnRedirect.current = false` inside an click handler effectively disables the automatic cleanup logic defined in the `SidebarProvider`.

Sources: [packages/base-ui/src/components/sidebar/base.tsx:32-73](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/base.tsx#L32-L73)

## Page Tree Rendering Pipeline

The sidebar displays content by rendering a page tree, which is generated via `createPageTreeRenderer`. This function creates a bridge between the raw data object and the UI components provided to it.

1.  **Registration**: A map of components (`SidebarFolder`, `SidebarItem`, etc.) is passed to `createPageTreeRenderer`.
2.  **Dispatch**: The renderer traverses the tree recursively; for each node type (`folder`, `page`, `separator`), it fetches the corresponding UI component from the context.
3.  **Recursion**: Folders trigger a nested `renderList` call to process their children, maintaining a running depth tally via `useFolderDepth`.

> [!TIP]
> The system allows overriding the UI for specific tree node types by passing `components` (e.g., `Folder`, `Item`, `Separator`) directly into the sidebar props, allowing for rich customization while reusing the built-in tree traversal logic.

Sources: [packages/radix-ui/src/components/sidebar/page-tree.tsx:31-98](https://github.com/blade47/fumadocs/blob/main/packages/radix-ui/src/components/sidebar/page-tree.tsx#L31-L98)

## Desktop vs. Drawer Mode Selection

The component determines its display strategy using `useMediaQuery`. This logic is encapsulated within `SidebarProvider`, ensuring that the rest of the application remains agnostic to the current view mode (drawer on mobile, fixed/full-width on desktop).

| Mode | Trigger | Behavior |
| :--- | :--- | :--- |
| `drawer` | `SidebarTrigger` | Sidebar becomes an overlayed side-drawer with an active `RemoveScroll` blocker. |
| `full` | `SidebarCollapseTrigger` | Sidebar is either fixed or hidden/minimized on the side of the main container. |

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

## Scroll Management and Auto-Navigation

The `useAutoScroll` hook is vital for navigation UX: when a sidebar item becomes `active`, it ensures that the item is scrolled into view within the `SidebarViewport`.

```typescript
export function useAutoScroll(active: boolean, ref: RefObject<HTMLElement | null>) {
  const { mode } = useSidebar();

  useEffect(() => {
    if (active && ref.current) {
      scrollIntoView(ref.current, {
        boundary: document.getElementById(mode === 'drawer' ? 'nd-sidebar-mobile' : 'nd-sidebar'),
        scrollMode: 'if-needed',
      });
    }
  }, [active, mode, ref]);
}
```

This ensures that regardless of whether the user is in a drawer or full-width view, the navigation tree automatically highlights and centers the user's current location.

Sources: [packages/base-ui/src/components/sidebar/base.tsx:407-418](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/base.tsx#L407-L418)

## Design Trade-offs

| Choice | Benefit | Cost |
| :--- | :--- | :--- |
| Context-based UI | High flexibility; easy to override components. | Adds overhead and potential for "Missing Context" errors. |
| Hook-based State | Simplifies inter-node communication. | Harder to debug state flows without specialized React DevTools. |
| Media Query Resolution | Responsive behavior out of the box. | Requires a layout wrapper to function; breaks if missing provider. |

Sources: [packages/base-ui/src/components/sidebar/base.tsx:116-120](https://github.com/blade47/fumadocs/blob/main/packages/base-ui/src/components/sidebar/base.tsx#L116-L120)

## Related

- [Layout System](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/rendering-ui/layout-system)
- [Page Trees](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/content-engine/page-trees)


## Sitemap

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