Skip to main content

Advanced

Custom page layouts

Different pages want different layouts — wide content, centered narrative, dashboard-style splits, reference tables. NookDocs's layout system lets you pick per page without dropping into full-headless mode.

Default NookDocs pages have a predictable shape — sidebar on the left, article in the middle, table of contents on the right. That works for 80% of content. The other 20% wants something different: a wide Mermaid diagram that overflows the default content max-width, a single-column narrative without a distracting TOC, a landing page with edge-to-edge hero cards, a reference table that needs 100% of horizontal space.

This guide covers NookDocs's per-page layout customisation. Lighter touch than going headless; uses frontmatter + component patterns to adjust layout page-by-page.

The built-in layout modes

NookDocs exposes layout as a frontmatter field. Set mode on any page to change its shape:

mode'default' | 'center' | 'wide' | 'custom'pathdefault: default

How the page renders inside the shell.

  • default — standard three-column (sidebar / article / TOC).

  • center — article centered, no TOC, narrower max-width. Good for long-form narratives.

  • wide — article fills available width, no TOC. Good for wide tables, diagrams, dashboards.

  • custom — article and TOC both removed; you render your own chrome inside the <Card>/<Tiles> primitives.

When to use each

default

Use for: reference docs, how-to guides, most content. TOC helps readers navigate long pages. Max-width keeps lines readable.

center

Use for: long-form narratives, editorial pieces, "explanation" mode Diátaxis content. Removing TOC focuses attention on the prose.

wide

Use for: reference tables with many columns, Mermaid diagrams, dashboards, code comparisons. Full horizontal space.

custom

Use for: landing pages, feature grids, hero sections. You control everything inside.

Example: narrow narrative

---
title: "Why we rate-limit per API key, not per IP"
description: Design decision with context + tradeoffs. Long-form explanation mode.
mode: center
---

We debated this decision for weeks. Per-IP limits are industry
standard — AWS, GitHub, Stripe all default to IP-based ...

(500 more words of narrative)

Rendered: no sidebar nav duplication, no TOC clutter. Reader scrolls linearly through the argument.

Example: wide reference table

---
title: HTTP status codes
description: Full list of response codes the API can return, with meanings, causes, and resolution steps.
mode: wide
---

| Code | Reason | HTTP status | Billing impact | Resolution |
|---|---|---|---|---|
| `invalid_api_key` | Missing Bearer prefix or revoked key | 401 | None | Regenerate key |
| `insufficient_credits` | Account balance below threshold | 402 | Block | Top up billing |
| `rate_limited` | Too many requests in 60s window | 429 | None | Back off + retry |
| `internal_server_error` | Unexpected server failure | 500 | Refund eligible | Contact support |

Wide layout gives every column breathing room. Default layout would wrap or truncate.

Example: landing page

---
title: "Acme Docs"
description: Developer documentation for the Acme platform.
mode: custom
---

<Tiles cols={3}>
  <Tile icon="rocket" href="/quickstart">
    ## Quickstart
    5-minute walkthrough to your first API call.
  </Tile>
  <Tile icon="code" href="/api-reference">
    ## API reference
    Every endpoint, every parameter, every response.
  </Tile>
  <Tile icon="sparkles" href="/ai-features">
    ## AI features
    Hosted LLM assistant, semantic search, agent-ready docs.
  </Tile>
</Tiles>

<HeroCard
  title="Ship your first integration today"
  description="Free sandbox account, real API keys, no credit card."
  cta="Sign up"
  href="https://acme.com/signup"
/>

Custom mode drops the article max-width + removes the TOC. You control visual composition via <Tiles>, <HeroCard>, <CardGroup>, <Columns>, etc.

Layout beyond mode — the <Columns> primitive

For mid-article layouts (two-column inside an otherwise default page), use <Columns>:

## Integration architecture

<Columns cols={2}>
  <div>
    Our API speaks REST + JSON. Authenticate with a Bearer token on
    every request. Rate limits per API key, not per IP.

    Responses stream back as Server-Sent Events for the assistant
    endpoint, standard JSON for everything else.
  </div>
  <div>
    <Frame caption="Request lifecycle from client to response">
      <Mermaid>
        sequenceDiagram
          Client->>API: POST /v1/payment
          API->>Stripe: Charge card
          Stripe-->>API: Success
          API-->>Client: 200 OK
      </Mermaid>
    </Frame>
  </div>
</Columns>

## Next steps

Mid-page columns work in any layout mode — use when one section benefits but most of the page is standard.

The max-width system

NookDocs exposes content width as a theme token:

--docs-content-max-width: 768px;       /* default mode article */
--docs-content-outer-max-width: 1280px; /* wide mode */
--docs-shell-max-width: 88rem;          /* whole shell (sidebar + article + TOC) */

These are CSS custom properties, not config keys — you set them through Custom CSS to change every page in your site, or via an inline style on a wrapper element to change one page:

/* site-wide, in your custom CSS */
#docs-root {
  --docs-content-max-width: 860px;
}

Most tenants never touch these. They're escape hatches.

Side rails

The article is flanked by two rails — the navigation sidebar on one side, the "On this page" table of contents on the other. Both rails reserve the same width, which is what keeps your article centred on the page:

--docs-sidebar-width: 288px;  /* navigation sidebar */
--docs-rail-width: 288px;     /* gutter reserved on BOTH sides */
--docs-toc-width: 220px;      /* how wide the TOC itself draws */

--docs-sidebar-border: 1px solid var(--docs-border);   /* rule between sidebar and article */
--docs-sidebar-divider: 1px solid var(--docs-border);  /* rules inside the sidebar */

Set either to none for a sidebar that separates by whitespace alone. They are independent — you can keep the outer rule and drop the internal ones, or the reverse.

Two things worth knowing:

  • --docs-toc-width is smaller than --docs-rail-width. The table of contents draws at its own width and sits against the inner edge of the rail; the leftover space stays empty. Change --docs-toc-width to make the TOC narrower or wider without moving your article.

  • The rail is reserved even on pages that have no table of contents, so your article stays in exactly the same place as readers move between pages.

If you widen --docs-sidebar-width, set --docs-rail-width to match — otherwise the article drifts off-centre by half the difference.

Sidebar scrollbar

When your navigation is longer than the viewport the sidebar scrolls. How its scrollbar behaves is part of the theme:

ValueBehaviour
alwaysVisible whenever the nav overflows. The default.
hoverFades in when the pointer enters the sidebar, out when it leaves.
hiddenNever drawn. The nav still scrolls by wheel, trackpad and keyboard.

The gutter is reserved in every mode, so the nav never shifts sideways as the scrollbar appears. Readers who have reduced motion enabled get the scrollbar without the fade.

This one is chosen by the theme rather than by config — Ember uses hover, every other theme uses always. Pick the behaviour you want by picking the theme, or override it yourself with Custom CSS:

/* hide the sidebar scrollbar on any theme */
.docs-sidebar,
.docs-sidebar * {
  scrollbar-width: none;
}
.docs-sidebar::-webkit-scrollbar,
.docs-sidebar *::-webkit-scrollbar {
  display: none;
}

API reference pages are the exception. Their right column holds request and response code samples rather than a table of contents, so the rail widens to fit them and the article narrows to compensate. This happens automatically — you don't configure it, and it doesn't affect your other pages.

Reading-mode toggles

Some tenants want readers to toggle between "reading mode" (center / narrow) and "reference mode" (wide / tables visible). NookDocs doesn't ship this out of the box — tenants with this need use one of:

  1. Separate pages — narrative version at /page, reference version at /page/reference. Linked from each other. Simpler than a toggle.

  2. <Visibility> audience split — sort of works for agent/human but not for "simplified/detailed" human variants.

  3. Custom frontend — full layout control, highest cost.

Combining layout + components

Layout mode sets the FRAME. Components set the CONTENT. They compose:

wide + CodeGroup

Wide mode lets wide code blocks breathe. Multi-language examples display all languages fully.

center + Steps

Long tutorial walkthroughs feel natural in center mode — reader scrolls linearly through numbered steps.

default + Accordion

Reference docs with occasional deep-dives — put the deep-dives in <Accordion> to keep the base page scannable.

custom + Tiles

Landing pages use <Tiles cols> grids to display many entry points at once. Custom mode removes the article max-width that would otherwise constrain.

Theme vs layout

Two different customisation axes:

AxisWhat it controlsScope
Theme (nookdocs.config.json#theme)Colours, fonts, spacing, radius, shadowsSite-wide, consistent across every page
Layout (page frontmatter mode)Page structure — article width, TOC presence, shell chromePer-page, can vary wildly

You can use mode: wide on a docs site with the larch theme (default) — layout + theme are orthogonal.

Limitations

  • No custom React components per page. You're working within the built-in component library. For truly custom rendering, see custom frontend.

  • mode: custom still uses the shell chrome (header, sidebar, footer). To remove ALL chrome, you need a custom frontend.

  • No fine-grained TOC control. Either TOC is there (default) or it's not (center / wide / custom). No "show only h2s, not h3s" toggle.

  • Max-width overrides are per-tenant, not per-page. To tweak per-page widths you'd need inline CSS.

Common layout mistakes

Related

Was this page helpful?

Last updated August 11, 2026

Custom page layouts | NookDocs | NookDocs