Shell reference
Layout is the shell every page renders inside. Your site never
mounts it directly — the renderer entries (@dreamlake/dockit/server
and /client) wrap each page in it — but understanding its anatomy
explains where everything on screen comes from.
Layout anatomy
The grid is 280px / minmax(0,1fr) / 280px, max-width 1320px; the
sidebar drops below md, the TOC below lg. Override --doc-sidebar-width
and --doc-toc-width independently in your site stylesheet. The content column caps
at 760px at lg and up, and carries data-pagefind-body so only page
prose enters the search index (the breadcrumb and footer are
data-pagefind-ignored). On noindex pages the marker is omitted
entirely, which keeps the whole page out of the index.
What Layout owns
- Providers —
ThemeProvider, theMDXProvidercarrying the component map, and the merge context below. - Search state — the open flag and query shared by the Topbar field and the SearchPalette.
- Merge state — a rAF-throttled scroll watcher flips a context
boolean when the page H1's bottom edge passes under the 40px topbar;
the page-top breadcrumb fades out and the topbar crossfades from
brand to breadcrumb. Components can read the flag with
useMerge(). - Page-top breadcrumb — a mono
Section / Titleeyebrow rendered above every H1 (including on/), hidden again once merged. - Head sync — with Vike's client routing,
<head>is not re-rendered on navigation; Layout syncsdocument.title({title} — {brand}), the description meta, and the robots meta (fornoindexpages) from the current page's frontmatter.
Layout props
Layout takes only { children } — the rendered page. Everything
else derives from Vike's page context, the navigation singleton, and
siteConfig.
Fullscreen pages
fullscreen: true in frontmatter turns off the content column, TOC,
breadcrumb, and footer, and gives the page the full viewport below the
topbar — for playgrounds and dashboards:
The sidebar stays (at md+), and the main region becomes an
overflow-auto panel sized to calc(100vh - 40px).
DocFooter
The prev/next navigation cards at the bottom of every non-fullscreen
page. You are looking at a live instance right now — scroll to the end
of this page: the cards below the content are <DocFooter />,
rendered by the Layout automatically.
Adjacency is the global page order — every page sorted by its
order frontmatter — not the sidebar grouping, so "Next" walks across
section boundaries in reading order. getAdjacentPages(path) finds
the current page in that sequence and returns its neighbors:
Rules:
hidden: truepages are skipped, so a reader walking the docs never lands on an internal page — unless dev mode (Cmd+Shift+D) is on, whichDocFooterhonors viauseHiddenToggle(it passes{ includeHidden: true }togetAdjacentPages).- If the current page is itself hidden, it still participates, so the reader can step back out.
- The footer renders nothing when the page has neither neighbor.
<DocFooter /> takes no props — the current URL comes from Vike's
page context and the sequence from the navigation singleton. Direct
use only matters in a custom layout.
Escape hatch
Everything Layout composes is exported individually (Topbar,
Sidebar, TOC, DocFooter, SearchPalette, mdxComponents), so a
custom shell can rearrange the pieces — see the
exports reference.
Sidebar
The 280px left rail listing every visible page, grouped by section. It is entirely derived — the conventions page covers the authoring side; this page covers behavior.
Sidebar anatomy
Each header carries a zero-padded item count on the right and a
fold affordance (−/+) on hover. The rail is sticky below the 40px
topbar, scrolls independently, and disappears below md.
Sections and order
- Groups come from each page's
sectionfrontmatter. - Group order = the
sectionOrderarray passed toinitDocs; unknown sections fall to the end alphabetically (so a new section shows up without breaking the nav). - Page order within a group =
orderfrontmatter (missing = 99).
Section headers are collapsible; the collapsed set persists in
localStorage (key sidebar-collapsed), so a reader's pruned sidebar
survives reloads. Navigating into a page whose group is folded
auto-unfolds that group.
Active-page matching is trailing-slash tolerant (/guides/ matches
/guides): the sidebar compares against normalizePath(urlPathname),
so prerendered HTML and client routing agree on aria-current even
when they disagree on the trailing slash. The same helper backs the
breadcrumbs, prev/next footer, and TOC edit links.
Tab filtering
With tabs declared, the sidebar shows only
groups containing at least one page under the active tab's
urlPrefix. The same section label can appear under several tabs —
the filter runs per tab, so each lens shows its own slice. With no
tabs registered, every section shows.
Hidden pages — Cmd+Shift+D
hidden: true pages stay out of the sidebar, search results, and
prev/next by default, while remaining reachable by direct URL — the
convention for internal/dev notes. Press Cmd+Shift+D and:
- hidden pages appear in the sidebar (with a lock chip),
- the topbar shows an orange dev-mode dot (click it to turn off),
- search and the DocFooter include them.
draft: true marks a page as awaiting review — it stays visible but
carries a DRAFT chip so reviewers can spot it.
hidden is about the reader's chrome. noindex is about robots and
generated artifacts — it emits a noindex meta and excludes the page
from pagefind and every LLM surface. Internal pages
usually want both.
Sidebar direct use
<Sidebar /> takes no props — groups come from the navigation
singleton (groupedPages / groupedVisiblePages), the active tab
from the current URL, and the fold state from localStorage. The
Layout mounts it on every page, fullscreen
included.
Table of contents
The right rail (visible at lg and up — you should see it now, to the
right) lists this page's headings with a scroll-spy: the animated SVG
rail and dot track your position as you read.
TOC anatomy
Headings come from the rendered DOM, not frontmatter: after each
navigation the TOC queries main.doc-content for anchored headings,
so anything MDX renders as an h2/h3 with an id shows up. H3s fold
under their parent H2; the fold state persists per page in
localStorage, and unfolding scrolls the active entry back into view.
What it indexes
- H2 headings always; H3 headings by default, rendered in a smaller mono style and foldable under their parent H2.
- Set
tocLevel: 2in frontmatter on long pages where H3 noise would crowd the rail:
Rail footer links
Below the headings, the rail carries three derived links:
| Link | Where it goes |
|---|---|
| View as Markdown | The page's .md twin generated by gen-llms.mjs — /reference/components/shell.md for this page. |
| Edit this page | {docsRepoUrl}/edit/{docsBranch}/{docsPagesPath}/<slug>/+Page.mdx — jumps straight to the source on GitHub. |
| Report an issue | {docsRepoUrl}/issues/new. |
TOC configuration
docsPagesPath (default docs/pages) is the repo-relative directory
holding pages/ — set it to match your layout, e.g. pages for a
repo-root site or packages/docs/pages for a nested package:
Note the split: docsRepoUrl is the workspace repo hosting the pages
(edit/issue links); repoUrl is the product repo behind the topbar's
GitHub icon. They often differ.
TOC direct use
<TOC /> takes no props; it reads headings from the rendered
main.doc-content and page metadata (tocLevel, the .md path) from
the navigation singleton. The Layout mounts it
on every non-fullscreen page.