DreamLake

Configuration

Everything configurable in dockit flows through one call — initDocs — made from your site.config.ts before the shell renders.

initDocs(options)

ts
import { initDocs, type PageFrontmatter } from '@dreamlake/dockit'

initDocs({
  site: { /* Partial<SiteConfig> */ },
  pageMetadata: import.meta.glob<PageFrontmatter>('./pages/**/+Page.mdx', { eager: true, query: '?frontmatter', import: 'default' }),
  rawPages: import.meta.env.DEV ? import.meta.glob<string>('./pages/**/+Page.mdx', {
    eager: true, query: '?raw', import: 'default',
  }) : undefined,
  sectionOrder: ['Getting started', 'Reference'],
  tabs: [],
})
OptionTypeRequiredPurpose
sitePartial<SiteConfig>yesBranding, URLs, chips — merged over neutral defaults.
pageMetadataeager ?frontmatter globone of theseMetadata-only loader keeps page bodies out of startup JavaScript.
pageseager glob of +Page.mdxone of theseLegacy module map; use either pages or pageMetadata.
rawPageseager ?raw globnoFeeds fallback full-text search. Prefer dev-only; production Pagefind searches built HTML.
sectionOrderstring[]noSidebar section order; unknown sections fall to the end.
tabsTabEntry[]noTopbar tab lenses and external links; omit for a tabless site.
searchSearchConfignoRuntime search options; overrides site.search when both are provided.

SiteConfig

FieldTypeEffect
brandstringTop-left brand; llms.txt heading.
subtitlestringMuted label after the brand.
repoUrlstringTopbar GitHub icon (empty hides it).
docsRepoUrlstringBase for Edit/issue links in the TOC rail.
docsBranchstringBranch in the edit link (default main).
breadcrumbRootstringLeftmost crumb (empty omits it).
urlstringPublic origin — absolute URLs in LLM artifacts.
skillstringAgent-skill name (skills/<skill>/, <skill>.zip).
summarystringOne-liner: llms.txt blockquote + skill description.
skillTriggersstring[]?Curated task phrases for the generated skill's "Use when:" trigger list; unset falls back to the site's section names.
versionChipsVersionChip[]?Topbar chips (see below). Individual tabs can override this via TabDef.versionChips.
gitHashstring?Git-hash chip (empty hides it).
docsPagesPathstring?Repo-relative pages dir for edit links (default docs/pages).
themeToggle'cycle' | 'segmented'?Topbar theme control: single cycling button (default) or the three-button slider — see Theming.
mdxComponentsRecord<string, Component>?Site-specific MDX tags merged over the library's provider map — pages use them without per-page imports.
headScriptsstring[]?External script URLs injected as <script src defer> into every page head (e.g. the Studio design-integration bridge). URLs only; non-URL entries are dropped.
searchSearchConfig?Runtime search options; see Search for multisite indexing.
indexableboolean?Search-engine visibility. Default false (org policy): every page carries noindex, nofollow unless the site opts in with indexable: true. In-site search, llms.txt, and skills are unaffected.

skillTriggers phrases should read as task descriptions — "theming the docs shell", "wiring Netlify deploys" — since an agent matches them against what it is currently doing. See LLM-readable docs for where they land.

VersionChip

ts
interface VersionChip {
  label: string      // left segment, e.g. 'dockit'
  version: string    // right segment, rendered as v<version>
  dropdown?: boolean // true → version switcher
  prefix?: string    // label prefix; defaults to 'v', '' for revisions
  manifestUrl?: string // defaults to '/versions.json'; path or absolute URL
}

Each chip renders as a <VersionBadge> — also exported from the library, so a site can place one outside the topbar:

tsx
import { VersionBadge } from '@dreamlake/dockit'

<VersionBadge label="dockit" version="0.2.0" dropdown />

prefix controls display only. Use prefix: '' for a revision such as main · abc1234; it does not create or imply a package release.

With dropdown, manifestUrl selects the version list. A relative path is fetched from the production origin (siteConfig.url) first, then from the current origin; local development tries its own origin first. An absolute HTTP(S) URL is fetched directly. Cross-origin manifests need a CORS header. Without dropdown, the badge displays the supplied version and does not fetch a manifest.

Use a separate manifest for each product. This site selects /dockit-versions.json for Dockit's 0.2.14 badge; its historical docs-build manifest /versions.json has a separate version sequence. The Python tab shows a main revision without a dropdown. See Releases & versioning.

TabDef

ts
interface TabDef {
  id: string        // stable key
  label: string     // strip label
  numeral: string   // editorial numeral ('I', 'II', …)
  landing: string   // click target
  urlPrefix: string // scoping prefix for the sidebar filter
  versionChips?: VersionChip[] // per-tab override of site.versionChips
}

Per-tab version chips

versionChips on a tab overrides the global site.versionChips whenever that tab is active:

  • Omit the field → the tab inherits the global chips (the default).
  • [] → no chips render on that tab.
  • A non-empty array → exactly those chips render, replacing the global list for that tab only.

The active tab is derived from the URL's first segment (same rule the sidebar filter uses), so the chips switch as the reader moves between tabs. A CLI-focused site can scope each surface to its own version:

ts
tabs: [
  // Inherits site.versionChips
  { id: 'overview', label: 'Get Started', numeral: 'I',
    landing: '/', urlPrefix: '/get-started' },
  // cli-only on the CLI tab
  { id: 'cli', label: 'CLI', numeral: 'II',
    landing: '/cli', urlPrefix: '/cli',
    versionChips: [{ label: 'cli', version: '1.4.0' }] },
  // py-only on the Python tab
  { id: 'python', label: 'Python', numeral: 'III',
    landing: '/python', urlPrefix: '/python',
    versionChips: [{ label: 'py', version: '0.9.2' }] },
  // no chips on the design tab
  { id: 'python-design', label: 'Design', numeral: 'IV',
    landing: '/design', urlPrefix: '/design',
    versionChips: [] },
],

TabEntry is TabDef | ExternalTabDef. External entries share the strip but link to another site, never become active, and scope no local pages:

ts
interface ExternalTabDef {
  label: string
  href: string // absolute destination URL
  external: true
}

internalTabs() returns only page-scoping tabs; isExternalTab(entry) is the exported type guard.

SearchConfig

ts
interface SearchConfig {
  mergeIndexes?: MergeIndexDef[]
}

interface MergeIndexDef {
  url: string   // remote Pagefind bundle directory
  label: string // source badge shown on remote results
}

Remote indexes require compatible Pagefind formats and CORS. A failed remote index leaves local search available. See Search for the complete indexing and palette workflow.

PageMeta

The parsed frontmatter shape — field-by-field effects are documented in Authoring:

ts
interface PageMeta {
  path: string
  title: string
  section: string
  order: number
  description?: string
  draft?: boolean
  hidden?: boolean
  noindex?: boolean
  tocLevel?: 2 | 3
  fullscreen?: boolean
}

The dev: true frontmatter shorthand folds into hidden + noindex at parse time — PageMeta carries the resolved flags. Path matching against PageMeta.path should go through normalizePath / findPage (both exported), which tolerate a trailing slash.

The init functions

initDocs is sugar over four setters, each also exported for piecemeal setups. All mutate module-level singletons in place, so components holding an imported reference always see current data.

ts
function initDocs(opts: InitDocsOptions): void

function defineSiteConfig(cfg: Partial<SiteConfig>): void

function initNavigation(
  modules: Record<string, { frontmatter?: PageFrontmatter }>,
  sectionOrder?: string[],
): void

function initSearchIndex(rawSources: Record<string, string>): void

function initTabs(tabs: TabEntry[]): void
FunctionPopulatesFrom
defineSiteConfigsiteConfigyour site overrides, merged over defaults.
initNavigationpages, groupedPages, groupedVisiblePagesthe eager page glob's frontmatter.
initSearchIndexsearchIndex, rawMarkdownthe ?raw glob (dev search fallback).
initTabsTABSyour TabEntry[].

Navigation rail widths

Both rails default to 280px: the left sidebar appears at 768px and wider, and the right-hand TOC at 1024px and wider. Override --doc-sidebar-width and --doc-toc-width in your site stylesheet (after importing Dockit styles):

css
:root {
  --doc-sidebar-width: 300px;
  --doc-toc-width: 240px;
}

Use 240px for either rail to restore its previous width. The sidebar setting also applies to fullscreen layouts; those layouts omit the TOC. Mobile navigation is unchanged.

The sidebar uses a thin scrollbar with a stable gutter, preventing overflow changes from shifting section headings. Section labels stay on one line (with an ellipsis and full-label tooltip if needed); page titles can wrap normally.