DreamLake

Site config

A dockit site is wired by one callinitDocs — made from a side-effect module (conventionally site.config.ts) that both renderer entries import first, so the config lands before anything renders, on the server and on the client. There is no nav config anywhere: the sidebar, tabs, and search all derive from this call plus page frontmatter.

The full cookbook

A complete wiring example; adapt the routes and section names to your site:

site.config.tsts
import { initDocs, type PageFrontmatter } from '@dreamlake/dockit'

const pageMetadata = import.meta.glob<PageFrontmatter>('./pages/**/+Page.mdx', {
  eager: true,
  query: '?frontmatter', import: 'default',
})

// Pagefind indexes built HTML in production; keep full raw text in dev only.
const rawPages = import.meta.env.DEV
  ? import.meta.glob<string>('./pages/**/+Page.mdx', { eager: true, query: '?raw', import: 'default' })
  : undefined

initDocs({
  site: {
    brand: 'DreamLake',
    subtitle: 'Dockit',
    repoUrl: 'https://github.com/dreamlake-ai/dockit-workspace',
    docsRepoUrl: 'https://github.com/dreamlake-ai/dockit-workspace',
    docsBranch: 'main',
    breadcrumbRoot: 'Dockit',
    url: 'https://dockit.dreamlake.ai',
    skill: 'dockit',
    summary:
      'Dockit is the DreamLake documentation shell — a Vike + React + Tailwind v4 component library and site framework with sidebar/TOC/search, MDX authoring conventions, and a versioned Netlify deploy pipeline.',
    versionChips: [{ label: 'dockit', version: __DOCKIT_VERSION__,
      dropdown: true, manifestUrl: '/dockit-versions.json' }],
    docsPagesPath: 'docs/pages',
  },
  pageMetadata,
  rawPages,
  sectionOrder: ['Getting started', 'Build your site', 'Publishing', 'API', 'Shell', 'Content components', 'Python Autodoc'],
  tabs: [
    { id: 'dockit', label: 'Dockit', numeral: 'I', landing: '/', urlPrefix: '/get-started' },
    { id: 'reference', label: 'Reference', numeral: 'II', landing: '/reference/config', urlPrefix: '/reference' },
    { id: 'python-autodoc', label: 'Python Autodoc', numeral: 'III',
      landing: '/python-autodoc', urlPrefix: '/python-autodoc',
      versionChips: [{ label: 'autodoc-py', version: __AUTODOC_REVISION__, prefix: '' }] },
  ],
})

The two globs matter: pages (module glob) feeds navigation from frontmatter; rawPages (?raw glob) feeds the dev search index and the palette's markdown preview. initDocs fans out to defineSiteConfig, initNavigation, initSearchIndex, and initTabs — all singletons mutated in place, so components keep live references.

Configuration reference

The configuration reference is the canonical field-by-field API. Start with branding (brand, subtitle, repoUrl), documentation ownership (docsRepoUrl, docsBranch, docsPagesPath), and the public url. An empty repoUrl hides the GitHub icon; an empty breadcrumbRoot hides the root crumb.

Set skill, summary, and skillTriggers when generating AI-readable docs and skills. The examples below cover the configuration choices that need coordination with Vite or the page layout.

Version chips from Vite define

Chips render as [ label | v<version> ]. Hardcoding the version would drift, so this site injects it at build time from the real package.json, along with the git hash:

vite.config.tsts
const dockitPkg = JSON.parse(
  readFileSync(new URL('../packages/dockit/package.json', import.meta.url), 'utf-8'),
) as { version?: string }

const DOCKIT_VERSION = dockitPkg.version ?? '0.0.0'

const GIT_HASH = (() => {
  try {
    return execSync('git rev-parse --short=6 HEAD', { encoding: 'utf-8' }).trim()
  } catch {
    return 'dev'
  }
})()

export default defineConfig({
  define: {
    __DOCKIT_VERSION__: JSON.stringify(DOCKIT_VERSION),
    __GIT_HASH__: JSON.stringify(GIT_HASH),
  },
  plugins: [...dockit()],
})

TypeScript needs to know the globals exist:

env.d.tsts
/** Injected via Vite `define` in vite.config.ts. */
declare const __DOCKIT_VERSION__: string
declare const __GIT_HASH__: string

Then site.config.ts just references __DOCKIT_VERSION__ and __GIT_HASH__ — single source of truth, no lockfile parsing. A chip with dropdown: true opens a popover listing past deploys from /versions.json by default. Set manifestUrl for an independent product manifest; this site uses /dockit-versions.json. Set prefix: '' for source revisions such as main · 247f6ba, supplied here by the build-time __AUTODOC_REVISION__ constant. See Versioning.

Scoping chips per tab

By default the same chips show on every tab. A tab can override them with its own versionChips, so a multi-surface site shows only the relevant version on each tab:

ts
tabs: [
  // cli-only chip on the CLI tab
  { id: 'cli', label: 'CLI', numeral: 'I', landing: '/cli',
    urlPrefix: '/cli', versionChips: [{ label: 'cli', version: __CLI_VERSION__ }] },
  // no chip on the design tab
  { id: 'python-design', label: 'Design', numeral: 'II', landing: '/design',
    urlPrefix: '/design', versionChips: [] },
  // omit the field → inherits site.versionChips
  { id: 'guides', label: 'Guides', numeral: 'III', landing: '/guides',
    urlPrefix: '/guides' },
],

Omit versionChips to inherit the global list, set [] to hide chips on that tab, or pass an array to replace them for that tab only. See the Configuration reference.

Tabs

Tabs group pages by URL prefix. Give each tab an id, visible label and numeral, a landing page, and a urlPrefix matching its routes. The TabDef reference lists the complete shape; the Topbar documents the rendered control.

Filtering is by URL prefix, not frontmatter: /guides/theming belongs to the tab whose urlPrefix is /guides, full stop. The site root / and any unknown prefix resolve to the first tab, so orphan pages never leave the sidebar empty. Omit tabs (or pass []) for a tabless site — the strip disappears and the sidebar shows every section.

Section order

sectionOrder is the authored ordering of sidebar section groups. Sections are minted by frontmatter (section: Guides just works); any section not listed here falls to the end. Within a section, pages sort by their frontmatter order — see Authoring pages.

Skill triggers

skillTriggers feeds the generated agent skill's "Use when" clause. The LLM generator writes skills/<skill>/SKILL.md with a description an agent matches against before deciding to load the skill — good triggers name concrete tasks, not topics:

ts
skillTriggers: [
  'building or restyling a DreamLake docs site',
  'writing +Page.mdx pages with frontmatter',
  'configuring initDocs, tabs, or version chips',
],

Keep them short, verb-first, and distinct; they are concatenated into the skill description alongside summary.