/

Documentation Layout: Four Parts and a Search Box

A sidebar, a table of contents, a code block and a search index. The catalogue has 37 sidebars and exactly two tables of contents.

Serafim Korablev
Serafim Korablev
@korablev

A documentation site is four components and some prose: a sidebar that mirrors the file tree, a table of contents that tracks where you are, a code block that can be copied, and a search box. Everything else is writing.

The catalogue shows where the effort goes. 37 public components named sidebar, 47 named code, and exactly two tables of contents. The part that does the most for a reader is the part almost nobody builds.

The parts

Sidebar by Manu Arora expands on hover and collapses on mobile, and shadcn's Sidebar is the primitive version with the state handling already done. The sidebar guide covers the collapse behaviour that decides whether a docs nav is usable on a phone.

Table of Contents by hirael tracks the active heading as you scroll, and Table of Contents is the auto-scrolling variant that keeps the active item in view when the list is long.

Code Block and Code block are the two most-taken code components, and the code block guide covers the highlighting decision, which is the one with real bundle consequences.

What makes docs different from an app shell

The URL is the state. Every heading needs an anchor, the sidebar has to reflect the current path, and a deep link to a section has to land on that section. An app shell can keep its state in memory; docs cannot, because the whole point is that a link to one paragraph works.

Content is the product, so it renders on the server. A docs page whose body arrives via client-side fetch is invisible to search engines and answer engines. The server components guide has the rule: interactive parts are client components, prose is not.

The sidebar mirrors a file tree, which is why a file tree component and a docs nav share most of their logic: nesting, an expanded state, and one active item.

The table of contents detail

Scroll-spy is where these go wrong. Use an IntersectionObserver rather than a scroll handler, because a scroll handler runs on every frame and fights the browser's own scrolling.

Three rules follow. Each entry is a real link, so it works without JavaScript and a right-click can copy it. When several headings are visible at once, highlight the topmost rather than flickering between them. And when the reader clicks an entry, respect prefers-reduced-motion before smooth-scrolling, per the scroll animation guide.

Search is an index, not a box

Command Palette and Command give you the interface. The command palette guide makes the point that matters here: the component is an afternoon and the index is the project. For docs specifically, search over headings and paragraphs beats search over page titles by a wide margin, and that means building the index at build time.

The smaller parts are worth naming: Pagination for previous and next page links at the foot of an article, Callout for the highlighted notes, and a breadcrumb when the tree is more than two levels deep.

Where else to look

The honest list, because the answer is not always us:

SourceBest forTrade-off
Fumadocs / NextraA whole docs site from markdown, search includedYou adopt its layout and its conventions
DocusaurusVersioned docs at scaleA framework rather than components
A hosted docs productNever maintaining any of thisYour docs live somewhere else
21stThe individual parts, when the docs live inside your appYou assemble them

Taking one

Every component page has a live preview and the code. Installing goes through the shadcn CLI against our registry:

bash

That key comes from your 21st account, and installs require a membership. Set API_KEY_21ST once in your shell and the command works for anything in the catalogue.

Browse sidebar components →

Frequently asked

What does a documentation site actually need?
Four components and prose: a sidebar mirroring the file tree, a table of contents that tracks the active heading, a code block that can be copied, and search. The catalogue shows where effort goes: 37 public components named sidebar, 47 named code, and two tables of contents.
How should a table of contents track the active heading?
With an IntersectionObserver rather than a scroll handler, which runs every frame and fights the browser's own scrolling. Each entry stays a real link so it works without JavaScript, and when several headings are visible the topmost wins rather than flickering.
Why must docs pages render on the server?
Because content is the product. A page whose body arrives by client-side fetch is invisible to search engines and answer engines, so prose stays a server component and only the interactive parts, the sidebar toggle and the search dialog, become client components.
Is a command palette enough for docs search?
The palette is an afternoon and the index is the project. For documentation specifically, searching over headings and paragraphs beats searching page titles by a wide margin, and that means building the index at build time rather than querying at runtime.

Published

Aug 21, 2026

Read time

4 min

Tags

GuideLayoutReactDocs

Share