DreamLake

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

┌─ Topbar ────────────────────────────────────────────────┐
│ brand / subtitle [chips]   breadcrumb   tabs   search ⌘K│
├──────────┬───────────────────────────────┬──────────────┤
│ Sidebar  │  main.doc-content             │  TOC rail    │
│ 280px    │  breadcrumb                   │  280px       │
│ (md+)    │  {page MDX}                   │  (lg+)       │
│          │  DocFooter (prev/next)        │              │
└──────────┴───────────────────────────────┴──────────────┘
             SearchPalette (fixed overlay, ⌘K)

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

  • ProvidersThemeProvider, the MDXProvider carrying 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 / Title eyebrow 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 syncs document.title ({title} — {brand}), the description meta, and the robots meta (for noindex pages) 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:

mdx
---
title: Playground
section: Tools
fullscreen: true
---

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:

ts
import { getAdjacentPages } from '@dreamlake/dockit'

const { prev, next } = getAdjacentPages('/reference/components/shell')

Rules:

  • hidden: true pages are skipped, so a reader walking the docs never lands on an internal page — unless dev mode (Cmd+Shift+D) is on, which DocFooter honors via useHiddenToggle (it passes { includeHidden: true } to getAdjacentPages).
  • 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.

│ GETTING STARTED      05 │  ← section header (mono, click to fold)
│   Installation          │
│   Quick start           │  ← active page highlighted
│ APP CHROME         + 04 │  ← folded group (+ affordance, count stays)
│ DEV                  02 │
│   Gallery            🔒 │  ← hidden page, dev mode on
│   Contributing  [DRAFT] │  ← draft chip

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 section frontmatter.
  • Group order = the sectionOrder array passed to initDocs; unknown sections fall to the end alphabetically (so a new section shows up without breaking the nav).
  • Page order within a group = order frontmatter (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 vs noindex

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 /> 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

│ ON THIS PAGE          │
│ ●  Anatomy            │  ← dot rides the rail to the active heading
│ │  What it indexes    │
│ │   · sub heading     │  ← H3: smaller mono, foldable under its H2
│ │  Rail footer links  │
│ ┊                     │
│ ──────────────────────│
│ View as Markdown      │
│ Edit this page        │
│ Report an issue       │

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: 2 in frontmatter on long pages where H3 noise would crowd the rail:
mdx
---
title: Very long reference
tocLevel: 2
---

Below the headings, the rail carries three derived links:

LinkWhere it goes
View as MarkdownThe 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:

site.config.tsts
site: {
  docsRepoUrl: 'https://github.com/dreamlake-ai/dockit-workspace',
  docsBranch: 'main',
  docsPagesPath: 'docs/pages',
}

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.