DreamLake

Authoring pages

A page is a folder: pages/<slug>/+Page.mdx renders at /<slug> (nested folders nest the URL). Every page starts with a YAML block, and those fields are the whole authoring contract — URL, sidebar, search, and the LLM artifacts all derive from them. There is no nav config to edit. The parsed shape is exported as PageMeta.

Directory layout = URL

Every page is a +Page.mdx inside a folder; the folder path is the URL:

pages/
  index/+Page.mdx                →  /
  get-started/quickstart/+Page.mdx  →  /get-started/quickstart
  api/config/+Page.mdx           →  /api/config

index is special — it maps to the site root /.

Frontmatter fields

FieldTypeDefaultEffect
titlestringfolder nameSidebar label, <title>, breadcrumbs, search result title.
sectionstring''Sidebar group. New section strings just work — order them via sectionOrder in Site config.
ordernumber99Global sort key: sidebar position within the section AND the prev/next sequence.
descriptionstring<meta description>, search result blurb, llms.txt link blurb.
draftbooleanfalse"Awaiting review" chip in the sidebar; page stays visible.
hiddenbooleanfalseOut of sidebar/search/prev-next until dev mode (Cmd+Shift+D). Still reachable by URL.
noindexbooleanfalseEmits noindex, nofollow robots meta; excluded from pagefind and every LLM surface.
devbooleanfalseShorthand for hidden: true + noindex: true — an internal developer note in one flag (studio's convention).
tocLevel2 | 332 limits the right rail to H2 headings.
fullscreenbooleanfalseFull-viewport page: no content column, TOC, or footer.

A standard page:

mdx
---
title: Installation
section: Getting started
order: 1
description: Install the package and its peers.
---

An internal note, invisible to readers, robots, and agents:

mdx
---
title: Release runbook
section: Dev
order: 90
hidden: true
noindex: true
---

Conventions for order

Leave gaps (0, 1, 2 … 10, 11 … 20, 21) so pages can slot in without renumbering a whole section. This site numbers sections in tens.

Frontmatter is data, not markdown

Keep values plain strings — the generator that builds the LLM artifacts parses frontmatter with a simple flat key: value reader. Nested YAML structures will not survive the trip.

Sidebar auto-discovery

The rules, in full:

  1. Pages group by their section string. Sections render in the sectionOrder you pass to initDocs; sections not in that list fall to the end, alphabetically — a new section shows up without any config change.
  2. Within a section, pages sort by order (missing order = 99). Leave gaps between sections' order ranges (this site uses 0–4, 10–13, 20–23, …) so inserting a page never renumbers its neighbors.
  3. If the site declares tabs, the sidebar shows only pages whose URL falls under the active tab's urlPrefix.
  4. hidden: true pages stay out of the sidebar (and prev/next) until the reader toggles dev mode with Cmd+Shift+D.
Never edit a nav config — there isn't one

Adding a page is: create the folder, write frontmatter, done. Moving a page is: move the folder. Renaming a section is: change the string in the pages that use it (and sectionOrder if you pinned it).

Naming conventions

  • Folder names are kebab-case; they become URL segments.
  • Keep section strings short — they render as uppercase mono labels.
  • One H1 per page, matching (or elaborating) the frontmatter title. The H1 drives the topbar's brand-to-breadcrumb crossfade.
  • ## headings feed the right-rail TOC; keep them scannable and front-loaded (they are also the anchors search results deep-link to — see the search guide).

Markdown & MDX

Pages are MDX: GitHub-flavored markdown, plus imports and JSX where prose is not enough. The MDX component map restyles every primitive (headings, links, tables, code) to the shell's design — write plain markdown and it comes out right.

  • Headings get stable slug ids (rehype-slug); hover a heading to grab its anchor. H2/H3 feed the TOC in the right rail (tocLevel: 2 drops the H3s).
  • Internal links are root-relative (/guides/search) — the client router intercepts them; the LLM generator rewrites them to .md twins in the exported artifacts.

Code fences

Fences are highlighted by shiki with dual light/dark themes. The meta string takes a file="…" chip:

mdx
```bash file="terminal"
pnpm add @dreamlake/dockit
```
terminalbash
pnpm add @dreamlake/dockit
  • The language chip comes from the fence language.
  • The :set nu button toggles line numbers site-wide — flip it on one block and every block follows.
  • Copy grabs the raw text.

Callouts

<Callout> is in scope without an import (as are <Preview>, <StatusTable>, and <TestStatus>):

mdx
<Callout variant="warn" title="Careful">
  Markdown works inside callouts.
</Callout>

See the Callout page for variants.

Tables

GFM tables render with the template's hairline borders:

mdx
| Flag | Effect |
| --- | --- |
| `hidden` | Hidden until Cmd+Shift+D |

Live examples

For component demos, follow the Preview convention: a real component in examples/, imported twice — once as a module to render, once with ?raw to show its own source:

mdx
import Demo from '../../../examples/callout-demo'
import demoSrc from '../../../examples/callout-demo.tsx?raw'

<Preview source={demoSrc} filename="callout-demo.tsx">
  <Demo />
</Preview>

Images and assets

Files in public/ serve from the site root (/diagram.png). Prefer SVG; both themes should read well — test with the theme toggle (see Theming & CSS).