zudo-doc
GitHub repository

Type to search...

to open search from anywhere

Configuration

Created Mar 13, 2026Updated Aug 3, 2026Takeshi Takatsudo

The single zudoDoc() config reference — every field and its default.

A zudo-doc project is configured through one file: the root zfb.config.ts. It calls zudoDoc() with the fields you want to change; every other setting falls back to a documented default.

zfb.config.ts
import { defineConfig } from "zfb/config";
import { zudoDoc } from "@takazudo/zudo-doc/config";

export default defineConfig(
  zudoDoc({
    siteName: "My Docs",
    // …only the fields you chose; everything has a documented @default.
  }),
);

zudoDoc() merges your fields over the package defaults per field (you win), supplies the package data defaults (frontmatter schema, directive vocabulary, translations, color schemes, tag vocabulary) unless you override them, and returns a complete ZfbConfig — you spread nothing.

Note

The ZudoDocConfig type is the single source of truth for this reference. Every field carries a @default JSDoc annotation that shows on IDE hover; the tables below mirror those defaults verbatim. When this page and the type disagree, the type wins.

Info

The defaults here are the package defaults a fresh create-zudo-doc project inherits. This showcase enables far more (most features on, i18n, a full header nav) by passing those fields explicitly — do not read the showcase's rich config as the default baseline.

Home page

home

Layout options for the package-owned home page. The default keeps the home content band at the standard no-sidebar width.

Default: { wide: false }

Set wide to true when a larger multi-column category grid benefits from using most of the viewport:

zfb.config.ts
export default defineConfig(
  zudoDoc({
    siteName: "My Docs",
    home: { wide: true },
  }),
);

The setting applies to both / and locale-prefixed home pages such as /ja. It works through the package-owned routes, so the scaffolded root route stays the locked one-line re-export:

pages/index.tsx
export { default } from "@takazudo/zudo-doc/routes/index";

Type: { wide?: boolean } · Default: { wide: false }

Identity and URLs

siteName

Site name shown in the header and metadata. Page titles render as {page title} | {siteName}. The one field you almost always set.

Default: "Docs"

siteDescription

Site description used in metadata (<meta name="description">, llms.txt).

Default: ""

Home-hero logo. "auto" (the default) renders a generated deterministic SVG seeded by siteName — a framed "decorated plate" mark that adapts to light/dark automatically, so a fresh project gets a presentable hero with no asset work. Set a path string (e.g. "/img/logo.svg") to render your own asset as a theme-adaptive CSS mask, or false to hide the logo block entirely.

Run npx zudo-doc eject logo to materialize the generated mark as a real file: it writes public/img/logo.svg and flips this field to "/img/logo.svg", so you own an editable asset — tweak it, replace it, or reuse it elsewhere (e.g. for OGP) — instead of the request-time generated default. See Customizing → Rung 5 for the CLI flags.

Default: "auto"

siteUrl

Canonical site origin (e.g. "https://example.com") for sitemap / canonical / og:url. Empty = not set.

Default: ""

base

Public URL sub-path prefix mounted in front of every absolute asset URL (e.g. "/pj/my-site/"). "/" = root-mounted. All internal links (sidebar, nav, prev/next, search) are prefixed automatically.

Default: "/"

Note

Inline markdown links in MDX (e.g. [text](/docs/some-page)) are not rewritten for a non-root base — use relative links in content instead.

trailingSlash

Append a trailing / to extensionless internal hrefs.

Default: false

See Trailing-Slash Policy for how the rule splits between build time and the deployment host.

minifyHtml

Minify production HTML output from zfb build. Set false for readable output while debugging.

Default: true

githubUrl

GitHub repository URL shown in the header (via the github-link header item), or false to omit.

Type: string | false · Default: false

editUrl

"Edit this page" link base, or false to omit. The full URL is editUrl + contentDir + "/" + entryId.

Type: string | false · Default: false

noindex

Add noindex,nofollow to every page (for internal docs).

Default: false

See Avoid Robots Indexing.

head

Site-wide custom <head> extras (preconnect / preload / stylesheets / meta / alternateLinks). Omit to emit nothing extra.

Type: SiteHeadConfig · Default: undefined

metaTags

<meta> / OpenGraph / Twitter-card emission toggles.

Default: { description: true, keywords: false, ogImage: false, ogSiteName: true, twitterCard: false }

PropertyTypeDescription
descriptionbooleanEmit <meta name="description">
keywordsstring | false<meta name="keywords"> value, or omit
ogImagestring | falsePath for og:image / twitter:image, or omit
ogSiteNamebooleanEmit og:site_name
twitterCard"summary" | "summary_large_image" | falseTwitter Card type, or omit the block
twitterSitestring (optional)twitter:site handle
twitterCreatorstring (optional)twitter:creator handle

sitemap

Emit a sitemap route.

Default: false

See also the SEO guide for how metaTags and sitemap combine into a complete social-share + search-indexing setup.

What to do when a .md/.mdx link cannot be resolved: "warn" logs and continues, "error" fails the build, "ignore" is silent.

Type: "warn" | "error" | "ignore" · Default: "warn"

Color

colorScheme

Active color scheme name (must exist in colorSchemes). The two bundled schemes are Default Light and Default Dark.

Default: "Default Dark"

colorMode

Light/dark mode wiring, or false for a single fixed scheme.

Default: { defaultMode: "dark", lightScheme: "Default Light", darkScheme: "Default Dark", respectPrefersColorScheme: true }

PropertyTypeDescription
defaultMode"light" | "dark"Initial mode before any user preference
lightSchemestringScheme used in light mode
darkSchemestringScheme used in dark mode
respectPrefersColorSchemebooleanMatch the OS-level light/dark preference
colorMode: false, // single fixed scheme (colorScheme only)

See the Color reference for the ramp-native model and adding a custom scheme (via the colorSchemes escape hatch below).

Theme packs

Theme packs are installable design bundles layered on top of the color-scheme system above — every pack defines both its light and dark values, so the mode toggle keeps working on any pack. See the Theme Packs reference for the switcher UI, the theme CLI, and pack authoring.

themePack

Active theme pack slug. "default" is the stock zudo-doc look (no pack stylesheet loaded). Must be a member of the resolved themePacks list; an unknown slug fails the build loudly.

Default: "default"

themePackSwitcher

Mount the bottom-right theme-pack switcher flyout (and its browse-all dialog) on every page.

Default: false

themePacks

Enabled pack slugs, in switcher order — the list order is the switcher's Prev/Next cycle order and the browse-all grid order. undefined enables all bundled packs: "default" first, then the rest alphabetically. An explicit list is authoritative — it may omit "default" and reorder freely; duplicates or unknown slugs fail the build loudly.

Default: undefined

themePacks: ["default", "foundry"],

Content and i18n

docsDir

Directory (project-root-relative) holding the default-locale docs.

Default: "src/content/docs"

entryDocSlug

Route slug of the doc page the versions page links to as the "latest docs" entry point (and each past version's docs link). No leading or trailing slashes — e.g. "getting-started" or "overview/getting-started". Not validated at runtime; an invalid slug simply 404s.

Default: "getting-started"

defaultLocale

Default locale code (unprefixed routes).

Default: "en"

locales

Additional locales: code → { label, dir }. Each becomes a /<code>/docs/ route tree and a docs-<code> collection.

Default: {}

locales: {
  ja: { label: "JA", dir: "src/content/docs-ja" },
},

defaultLocaleOnlyPrefixes

Route prefixes served only in the default locale (never locale-prefixed). The language switcher omits them on affected pages.

Default: []

See Default-locale-only prefixes.

versions

Docs versions, or false for a single (unversioned) doc set. Each versioned section is served at /v/{slug}/docs/.

Type: VersionConfig[] | false · Default: false

PropertyTypeDescription
slugstringVersion identifier in the URL path
labelstringVersion-switcher display label
docsDirstringContent directory for this version's default-locale docs
localesRecord (optional)Per-locale content dirs for this version
banner"unmaintained" | "unreleased" | false (optional)Banner shown on this version's pages

See the Versioning guide.

mermaid

Enable mermaid diagram rendering in markdown.

Default: true

math

Enable KaTeX math rendering ($…$, $$…$$, fenced math).

Default: false

cjkFriendly

Enable zfb's CJK-friendly line-break / emphasis handling.

Default: false

Tags

tagVocabulary and tagGovernance are orthogonal — one is the runtime gate, the other the enforcement level. The vocabulary entries are supplied separately via the tagVocabularyEntries escape hatch.

docTags

Enable the /docs/tags + /docs/tags/[tag] tag index routes.

Default: false

tagPlacement

Where per-page tags render relative to the content.

Type: "after-title" | "before-pager" · Default: "after-title"

tagGovernance

Tag-governance enforcement level when the vocabulary is consulted ("off" / "warn" / "strict").

Default: "off"

tagVocabulary

Whether the tag vocabulary is consulted at runtime (exact-id recognition and grouped footer). Orthogonal to tagGovernance. This is the boolean gate — the entries themselves come from tagVocabularyEntries.

Default: false

See Tag governance.

Table of contents and headings

tocMinDepth

Minimum heading depth included in the TOC (2–4).

Default: 2

tocMaxDepth

Maximum heading depth included in the TOC (2–4).

Default: 4

Site Settings

designTokenPanel

Enable the interactive Design Token Panel (zdtp) for live editing of spacing, font, size, and color tokens.

Default: false

The panel works with zero extra config. To fully customize it, point designTokenPanelConfigModule at a host module — see Host Chrome Bindings.

sidebarResizer

Enable the draggable sidebar resizer.

Default: false

sidebarToggle

Enable the desktop sidebar collapse toggle.

Default: false

tocToggle

Enable the desktop table-of-contents collapse toggle — a chevron button pinned to the right edge of the viewport on xl screens (1280px and up).

Default: false

Collapsing the TOC hands its width to the content column, so the same page can be read at a wider measure. That is the point of the feature: wide tables and long code lines stop wrapping or scrolling sideways once the TOC is out of the way. The reader's choice is remembered, so it holds across pages and across visits.

The toggle drives the package default TOC only. If you replace the Toc slot through chromeBindingsModule, your own component renders unchanged and no toggle appears — see Host Chrome Bindings.

tocToggle vs. hide_toc

They solve different problems and can be used together. The hide_toc frontmatter is an author decision baked in at build time: the page ships without a TOC, and no reader can bring it back. tocToggle is a reader control: wherever the default TOC is rendered, the reader decides whether to see it right now. It changes nothing on a page that already opted out with hide_toc.

imageEnlarge

Enable click-to-enlarge for content images.

Default: false

findInPage

Mount the FindInPageInit island (Cmd/Ctrl+F find bar) in the body-end islands.

Default: false

Auto-enabled by create-zudo-doc's tauri feature for generated Tauri scaffolds (the generator emits findInPage: true when the tauri feature is selected; it ships with the next create-zudo-doc release). Self-gates on window.__TAURI_INTERNALS__, so it is a safe no-op outside a Tauri shell even when true. A host that overrides the BodyEndIslands chrome-bindings slot (part of ChromeHostBindings — see Host Chrome Bindings for the general seam) must mount the island itself — the package default only applies when the slot is left unset.

dynamicPageTransition

Enable the dynamic (view-transition) page-loading overlay.

Default: false

frontmatterPreview

Frontmatter-preview config (ignore-key overrides), or false to disable the preview panel.

Type: FrontmatterPreviewConfig | false · Default: false

PropertyTypeDescription
ignoreKeysstring[] (optional)Replaces the default ignore list
extraIgnoreKeysstring[] (optional)Adds to the defaults (ignored if ignoreKeys is set)

See the Frontmatter Preview reference.

docHistory

Enable per-page git history (Created/Updated + dropdown). In dev, history is served by @takazudo/zudo-doc-history-server on port 4322; in CI a generator emits static JSON.

Default: false

Note

Fresh scaffolds wire the real scanner-reachable DocHistory island into every generated document-route shape when this feature is selected. No chromeBindingsModule or route edit is required for the history button itself.

See the Document History guide.

docMetainfo

Show the Created/Updated/Author meta block on doc pages (extracted from git history at build).

Default: false

Metadata data requires a host binding

The docHistoryMeta slot defaults to {}. Point chromeBindingsModule at a module that binds it to the build-time history manifest. Fresh route stubs already consume that module; do not edit them. See Custom Components and Host Chrome Bindings.

The binding module must provide docHistoryMeta; with the default {} data slot, there is no metadata block to render. Follow the Document History guide for the paired docHistory setup.

bodyFootUtilArea

Body-foot utility area (doc-history / view-source), or false to disable.

Type: BodyFootUtilAreaConfig | false · Default: false

PropertyTypeDescription
docHistoryboolean (optional)Show the History button (requires docHistory: true)
viewSourceLinkboolean (optional)Show a raw-source link (requires githubUrl)

htmlPreview

Global HTML-preview sandbox config, or undefined to disable global injection into every <HtmlPreview> iframe.

Type: HtmlPreviewConfig | undefined · Default: undefined

PropertyTypeDescription
headstring (optional)Raw HTML injected into <head>
cssstring (optional)CSS injected as a <style> block
jsstring (optional)JS injected before </body>

Footer config (link columns / copyright / taglist), or false for no footer.

Type: FooterConfig | false · Default: false

PropertyTypeDescription
linksFooterLinkColumn[]Link columns
copyrightstring (optional)Copyright text (HTML allowed)

Each FooterLinkColumn has title, items ({ label, href }[]), and optional per-locale overrides.

headerNav

Primary header navigation items.

Default: []

PropertyTypeDescription
labelstringDisplay text
labelKeystring (optional)i18n translation key (overrides label)
pathstringTarget path
categoryMatchstring (optional)Links this tab to a sidebar category
versionedboolean (optional)Whether this item's link carries the active /v/{version} prefix. Default true — see Header Navigation
headerNav: [
  { label: "Guides", path: "/docs/guides", categoryMatch: "guides" },
  { label: "Reference", path: "/docs/reference", categoryMatch: "reference" },
],

See How to Structure Navigations.

headerRightItems

Header right-hand-side items (toggles, switchers, links), in order.

Default: [{ type: "component", component: "theme-toggle" }]

typeExtra fieldsDescription
"component"component"theme-toggle", "language-switcher", "version-switcher", "github-link", "search"Built-in header component
"trigger"trigger"design-token-panel", "ai-chat"Opens a panel (requires the feature)
"link"href, label?, ariaLabel?, icon?Custom link
"html"htmlRaw HTML

AI assistant

aiAssistant

Enable the AI-chat assistant route (/api/ai-chat, SSR).

Default: false

Running a live assistant requires a deploy adapter, per-IP KV, an Anthropic secret, and the AI_CHAT_DAILY_SPEND_CAP Durable Object migration when the exact cap is enabled — see Customizing → Deploy path and the AI Assistant API. These are host-owned pieces: the package/scaffold supplies a safe placeholder route, not the showcase's live handler, Worker entry, or Durable Object class.

aiChatDemoMode

Short-circuit /api/ai-chat with a fixed "disabled" reply (no API key, KV, Durable Object, rate limiter, or provider fetch touched). Set false to enable live Claude-backed chat.

Default: false

aiChatAllowedOrigins

Allowed CORS origins for /api/ai-chat when not in demo mode. Empty = block all cross-origin browser requests.

Default: []

aiChatGlobalDailyLimit

Exact Anthropic fetch-admission limit per UTC day across all IPs, or false to skip the exact cap. Provider/network failure does not refund an admitted slot.

Type: number | false · Default: false

Generation and integrations

llmsTxt

Emit an llms.txt route summarising the docs.

Default: false

See llms.txt.

changelogs

Changelog generation config(s), or false to disable.

Default: false

See the Changelog guide.

claudeResources

Claude-resources ingestion config, or false to disable.

Type: { claudeDir; projectRoot?; scanRoot? } | false · Default: false

claudeResources: { claudeDir: ".claude" },

See the Claude Resources guide.

Routing seams

packageOwnedRoutes

Build-time package-owned route injection. When true, doc routes are injected from the package (no project-shipped pages/*.tsx layout stubs needed). Set false only if your project ships its own doc-route stubs.

Default: true

chromeBindingsModule

Project-root-relative path to a host module exporting a chromeBindings object built with defineChromeBindings (from @takazudo/zudo-doc/chrome-bindings; only consumed when packageOwnedRoutes is on). Omit to keep the injected chrome shim at its package-default stubs.

Default: undefined

See Host Chrome Bindings.

Escape-hatch fields

These override non-serializable / data defaults. They travel the import graph rather than being JSON-serialized, so they can carry functions, Zod types, and component maps.

buildDocsSchema

Replace the default docs-frontmatter Zod schema builder entirely. When omitted, zudoDoc() builds the package default (@takazudo/zudo-doc/docs-schema), governance-aware from tagGovernance + tagVocabularyEntries.

Type: () => ZodType · Default: undefined (package default used)

This is how you add custom frontmatter keys — see Customizing → Rung 1.

colorSchemes

Override the color-scheme palette map. When omitted, the two shipped schemes (Default Light / Default Dark) are used.

Type: Record<string, ColorScheme> · Default: undefined

translations

Override the UI-string translation table. When omitted, the shipped en/ja/de defaults are used.

Type: PresetTranslations · Default: undefined

directives

Override the directive → JSX-component-name map. When omitted, the canonical seven are used.

Type: DirectiveVocabulary · Default: undefined

Warning

directives replaces the vocabulary wholesale. Preserve the canonical directives when adding one, or existing :::note, :::warning, and other built-ins stop resolving.

zfb.config.ts
import { defaultDirectiveVocabulary } from "@takazudo/zudo-doc/directive-vocabulary-defaults";

export default defineConfig(
  zudoDoc({
    directives: {
      ...defaultDirectiveVocabulary,
      callout: "Callout",
    },
  }),
);

See the Directives Registry for the complete component-registration recipe.

tagVocabularyEntries

The tag-vocabulary entries array (distinct from the boolean tagVocabulary gate). Threaded into the route-context virtual module and consulted by the governance-aware default schema builder.

Type: readonly PresetTagVocabularyEntry[] · Default: []

Warning

Do not conflate tagVocabulary (a boolean gate) with tagVocabularyEntries (the entries array). They are separate fields — the gate decides whether the vocabulary is consulted; the entries are what it consults.

Shell passthrough fields

These are host-owned ZfbConfig shell fields, not part of Settings.

port

Dev/preview server port.

Default: 4321

adapter

Deploy-target adapter package name (e.g. "@takazudo/zfb-adapter-cloudflare"). Omit for a pure static build.

Default: undefined (pure static build)

bundle

zfb bundler options (exclude / mainFields / external), passed through verbatim when set.

Default: undefined

An extended project as reference

This showcase's own zfb.config.ts is the canonical "extended project" example — it spreads a typed settings object and passes genuinely showcase-specific data blocks (tag vocabulary, custom translations) through the escape-hatch fields, then adds the shell fields (port, adapter, bundle):

zfb.config.ts (this showcase)
export default defineConfig(
  zudoDoc({
    ...settings,
    tagVocabularyEntries: tagVocabulary,
    translations,
    chromeBindingsModule: "./src/chrome-bindings.tsx",
    port: 4321,
    adapter: "@takazudo/zfb-adapter-cloudflare",
    bundle: { exclude: ["e2e/fixtures/**"] },
  }),
);

A minimal project needs none of that — just the handful of fields it changes.

Revision History

Takeshi TakatsudoCreated: 2026-03-14T08:14:41+09:00Updated: 2026-08-04T01:35:32+09:00

AI Assistant

Ask a question about the documentation.

Preview theme

Loading theme previews…