Configuration
Global settings and configuration reference for zudo-doc.
zudo-doc is configured through a small set of files in the src/config/ directory and the root zfb.config.ts.
Site Settings
The main settings file is src/:
export const settings = {
colorScheme: "Default Dark",
colorMode: {
defaultMode: "dark",
lightScheme: "Default Light",
darkScheme: "Default Dark",
respectPrefersColorScheme: true,
},
siteName: "zudo-doc",
siteDescription: "Documentation base framework...",
base: "/",
trailingSlash: true,
docsDir: "src/content/docs",
locales: {
ja: { label: "JA", dir: "src/content/docs-ja" },
},
mermaid: true,
noindex: false,
editUrl: false,
githubUrl: "https://github.com/zudolab/zudo-doc",
siteUrl: "https://zudo-doc.takazudomodular.com",
sitemap: true,
designTokenPanel: true,
docMetainfo: true,
docTags: true,
frontmatterPreview: {},
math: true,
docHistory: true,
claudeResources: {
claudeDir: ".claude",
},
headerNav: [
{ label: "Getting Started", labelKey: "nav.gettingStarted", path: "/docs/getting-started", categoryMatch: "getting-started" },
{ label: "Guides", labelKey: "nav.guides", path: "/docs/guides", categoryMatch: "guides" },
{ label: "Reference", labelKey: "nav.reference", path: "/docs/reference", categoryMatch: "reference" },
{ label: "Claude", labelKey: "nav.claude", path: "/docs/claude", categoryMatch: "claude" },
],
};Note
The defaults shown here reflect this showcase's settings.ts, which enables most features so every capability is on display. A fresh project scaffolded with create-zudo-doc starts more minimal — many features (for example docHistory, designTokenPanel, sidebarToggle, sidebarResizer, llmsTxt, and githubUrl) default to off/disabled and are opted in during the scaffold prompts. When in doubt about a default, treat the upstream scaffold as the baseline and this page as the "everything enabled" reference.
colorScheme
The active color scheme name. Must match a key in src/.
Available built-in schemes: Default Light and Default Dark. You can add custom schemes in src/.
Tip
See the Color guide for a full list of available schemes, previews, and instructions on adding custom schemes.
colorMode
Configures light/dark mode behavior. Set to false to disable color mode switching entirely and use only the scheme specified in colorScheme.
When enabled, accepts a ColorModeConfig object:
| Property | Type | Description |
|---|---|---|
defaultMode | "light" | "dark" | The initial color mode before any user preference is applied |
lightScheme | string | Color scheme name to use in light mode |
darkScheme | string | Color scheme name to use in dark mode |
respectPrefersColorScheme | boolean | When true, automatically matches the user's OS-level light/dark preference |
colorMode: {
defaultMode: "light",
lightScheme: "Default Light",
darkScheme: "Default Dark",
respectPrefersColorScheme: true,
},
// or disable color mode switching:
colorMode: false,base
The base path for deploying to a subdirectory. Set this when your site is served from a subpath rather than the root domain.
Default: "/"
For example, to serve the site at https::
base: "/my-docs",All internal links (sidebar, navigation, prev/next, search) are automatically prefixed with the base path. The value flows through to zfb's build pipeline so emitted asset URLs and route paths share the same prefix.
Note
Inline markdown links within MDX content (e.g., [link text](/docs/some-page)) are not automatically rewritten. When using a non-root base, use relative links in content files instead.
trailingSlash
Controls whether URLs end with a trailing slash. When true, all internal links are generated with a trailing slash (e.g., / instead of /). The build-time URL helpers in @takazudo/ enforce this policy across every emitted route — see Trailing-Slash Policy for how the rule splits between build time and the deployment host.
Default: true (the showcase sets this to true; create-zudo-doc scaffolded projects also default to true)
trailingSlash: true,Note
Some hosting platforms (e.g., AWS Amplify, Cloudflare Pages) work better with trailing slashes enabled. If you experience 404 errors on page navigation, try setting this to true.
When enabled, the dev server automatically redirects URLs without a trailing slash to their trailing-slash version with a 301 redirect (e.g., / → /) so navigation behaves the same way locally as on production. Static assets (files with extensions like .js, .css, .png) are excluded from the redirect.
Note
Earlier versions of this doc referenced / and / as additional redirect exclusions. Those are legacy Astro-era paths; zfb does not emit them. They are preserved in the redirect skip-list only for backward compatibility with existing cached links.
onBrokenMarkdownLinks
Controls how broken internal markdown links are handled during the build. This applies to relative [text](. links resolved by zudo-doc's link resolver plugin.
"warn"— logs a warning but continues the build"error"— throws an error and fails the build"ignore"— silently skips broken links without any output
Type: "warn" | "error" | "ignore"
Default: "warn"
onBrokenMarkdownLinks: "error", // fail the build on broken linksdocsDir
The directory path (relative to the project root) where English documentation MDX files are stored. zfb's content engine globs this directory, so it can point to any location inside the project.
Default: "src/
docsDir: "docs", // content in ./docs/ at project rootThis is similar to Docusaurus' docs.path option — useful when using zudo-doc as a documentation tool for a larger project where docs live at the project root level.
defaultLocale
The BCP 47 code for the default (prefix-less) locale. Used by zfb's i18n router to map the root / routes.
Type: string
Default: "en"
defaultLocale: "en",locales
A map of additional locale configurations. Each key is a locale code, and the value is an object with label (display name for the language switcher) and dir (content directory path).
Default: {}
locales: {
ja: { label: "JA", dir: "src/content/docs-ja" },
ko: { label: "KO", dir: "src/content/docs-ko" },
},For each locale entry, zudo-doc automatically:
Creates a zfb content collection (
docs-{code})Registers the locale in zfb's i18n routing
Adds it to the language switcher
defaultLocaleOnlyPrefixes
An array of URL prefixes that exist only in the default locale. Pages under these prefixes are not translated and should have no mirror under any locale prefix. The language switcher omits them when on an affected page.
Type: string[]
Default: []
defaultLocaleOnlyPrefixes: [
"/docs/claude-md/",
"/docs/claude-skills/",
],See Default-locale-only prefixes for the full authoring workflow.
versions
Configures multi-version documentation. When set to an array of VersionConfig objects, zudo-doc creates versioned content collections and adds a version switcher to the sidebar. Each versioned section is accessible at /. Set to false to disable versioning.
Type: VersionConfig[] | false
Default: false
Each VersionConfig object accepts:
| Property | Type | Description |
|---|---|---|
slug | string | Version identifier used in the URL path (e.g., "1.0", "v1") |
label | string | Display label shown in the version switcher (e.g., "1.0.0") |
docsDir | string | Content directory path for this version's English docs |
locales | Record (optional) | Per-locale content directories for this version ({ ja: { dir: "..." } }) |
banner | "unmaintained" | "unreleased" | false (optional) | Banner shown on all pages in this version |
versions: [
{
slug: "1.0",
label: "1.0.0",
docsDir: "src/content/docs-v1",
banner: "unmaintained",
},
],
// or disable versioning:
versions: false,Tip
See the Versioning guide for details on how version switching works and how to configure banners for unmaintained or unreleased versions.
siteName
The site name displayed in the header and used in page titles. Page titles are formatted as {page title} | {siteName}.
siteDescription
A short description of the site. Used in meta tags for SEO and social sharing.
Default: ""
siteUrl
The full base URL of your site (e.g., "https:). Required for generating absolute URLs in the sitemap.
Default: ""
metaTags
Fine-grained control over which <meta> tags are emitted. Set individual sub-fields to false to omit a tag entirely.
Type: MetaTagsConfig
| Property | Type | Description |
|---|---|---|
description | boolean | Emit <meta name="description">. Default true |
keywords | string | false | Emit <meta name="keywords"> with this value. false = omit. Default false |
ogImage | string | false | Path for og:image (and twitter:image). false = omit. Default false |
ogSiteName | boolean | Emit og:site_name. Default true |
twitterCard | "summary" | "summary_large_image" | false | Twitter Card type. false = omit entire block. Default false |
twitterSite | string (optional) | twitter:site handle (e.g. "@yourbrand") |
twitterCreator | string (optional) | twitter:creator handle |
metaTags: {
description: true,
keywords: false,
ogImage: "/img/ogp.png",
ogSiteName: true,
twitterCard: "summary_large_image",
twitterSite: "@yourbrand",
},noindex
When true, adds noindex and nofollow meta tags to all pages. Useful for internal documentation sites that should not be indexed by search engines.
Default: false
See Avoid Robots Indexing for a full explanation of the two complementary behaviors this setting activates (<meta name="robots"> and robots.txt).
mermaid
Enables Mermaid diagram support. When true, fenced code blocks with the mermaid language identifier are rendered as diagrams. When false, mermaid code blocks are displayed as plain code.
Default: true
math
Enables KaTeX math equation rendering. When true, inline math ($...$), block math ($$...$$), and fenced math code blocks are rendered as equations.
Default: true
cjkFriendly
Enables CJK-friendly typography adjustments. When true, applies improved line-breaking and word-wrap behavior for Chinese, Japanese, and Korean text throughout the documentation.
Type: boolean
Default: false
cjkFriendly: true,editUrl
Base URL for "Edit this page" links. The full URL is constructed as editUrl + contentDir + "/" + entryId. Set to false to disable edit links.
Default: false (disabled)
editUrl: "https://github.com/my-org/my-repo/edit/main/",
// or disable:
editUrl: false,githubUrl
The repository URL shown as the GitHub link in the site header. When set to a string, a GitHub icon link to that URL appears in the header's right-side items (wherever the github-link component is placed in headerRightItems). Set to false to omit the header GitHub link.
Type: string | false
Default: false (the create-zudo-doc scaffold leaves it off; this showcase sets the repo URL)
githubUrl: "https://github.com/my-org/my-repo",
// or omit the header GitHub link:
githubUrl: false,sitemap
Enables automatic sitemap.xml generation during build. The sitemap includes all built HTML pages except 404.
Default: true
llmsTxt
Enables automatic llms.txt generation during build. When true, an llms.txt file is generated at the site root listing all documentation pages with their titles and descriptions. This file follows the llms.txt specification and helps AI assistants discover and index your documentation content.
Type: boolean
Default: false
llmsTxt: true,docMetainfo
Shows metadata (created date, last updated date, author) under the page title. Dates and author are extracted from git history at build time.
Default: true
docTags
Enables tag support for documentation pages. When true, pages can use the tags frontmatter field, and tag index pages are generated at /.
See the Tags guide for a full walkthrough.
Default: true
tagPlacement
Controls where the per-page tag badge row renders on doc pages.
Type: "after-title" | "before-pager"
Default: "after-title"
"after-title"— the badge row appears directly below the page title, above the main content."before-pager"— the badge row appears at the bottom of the content, immediately above the previous/next pager.
tagPlacement: "before-pager",Has no effect when docTags is false or when a page carries no tags.
tagGovernance
Enforcement level applied when the tag vocabulary is active. See Tag governance for the full reference.
Type: "off" | "warn" | "strict"
Default: "warn"
tagVocabulary
Whether tag-vocabulary.ts is consulted at runtime (alias resolution, deprecation filtering, grouped footer). Set to false to ignore the file entirely regardless of tagGovernance. See Tag governance for details.
Type: boolean
Default: true
frontmatterPreview
Displays custom frontmatter fields as a compact key/value table directly beneath the page title. Framework-managed keys (title, description, sidebar_position, etc.) are hidden by default so only project-specific metadata is shown. Set to false to disable the block on all pages.
Type: FrontmatterPreviewConfig | false
Default: {} (enabled with built-in ignore list)
The FrontmatterPreviewConfig object accepts:
| Property | Type | Description |
|---|---|---|
ignoreKeys | string[] (optional) | Completely replaces the default ignore list. When set, extraIgnoreKeys is ignored |
extraIgnoreKeys | string[] (optional) | Additional keys to ignore on top of the defaults. Has no effect when ignoreKeys is also set |
// Extend the default list:
frontmatterPreview: {
extraIgnoreKeys: ["reviewed_by", "internal_id"],
},
// Replace the default list entirely:
frontmatterPreview: {
ignoreKeys: ["title", "description", "sidebar_position"],
},
// Disable:
frontmatterPreview: false,Tip
See the Frontmatter Preview reference for the full default ignore list and a live demo.
designTokenPanel
Enables the interactive Design Token Panel. When true, a palette icon appears in the header and users can open a tabbed panel to tweak spacing, font, size, and color tokens in real-time. Changes are persisted in localStorage and can be exported/imported as JSON.
Default: false (set to true to enable)
Tip
See the Design Token Panel reference for a full tour of the four tabs and the JSON export workflow.
aiAssistant
Enables the AI assistant chat widget. When true, a chat button appears in the page that opens an AI-powered assistant for answering questions about your documentation. The chat API runs as a Cloudflare Workers SSR endpoint (pages/) — requires ANTHROPIC_API_KEY, DOCS_SITE_URL, and a RATE_LIMIT KV namespace configured in wrangler.toml.
Type: boolean
Default: false
aiAssistant: true,aiChatDemoMode
When true, the POST /api/ai-chat endpoint returns a fixed "disabled on this demo" reply without touching any API key, KV namespace, or rate limiter. Set to false in downstream projects that wire up a real ANTHROPIC_API_KEY to enable live Claude-backed chat.
Type: boolean
Default: true
aiChatAllowedOrigins
Allowed CORS origins for POST /api/ai-chat when aiChatDemoMode is false. Non-matching origins receive no Access-Control-Allow-Origin header, so browsers block the request. An empty array (default) blocks all cross-origin browser requests while still allowing same-origin requests.
Type: string[]
Default: []
aiChatAllowedOrigins: ["https://your-docs-site.example.com"],aiChatGlobalDailyLimit
Optional global daily request ceiling across all IPs as a cost backstop. false (default) disables the ceiling. When set to a positive integer (e.g. 500), the endpoint returns HTTP 429 once that many requests have been served in the current UTC day. Has no effect in demo mode.
Type: number | false
Default: false
aiChatGlobalDailyLimit: 500,sidebarToggle
Enables the sidebar collapse toggle. When true, a button in the sidebar header allows users to collapse the sidebar entirely, giving more horizontal space for content. The collapsed state is persisted in localStorage.
Type: boolean
Default: false
sidebarToggle: true,sidebarResizer
Enables sidebar width resizing. When true, a drag handle appears at the sidebar's right edge, allowing users to drag and resize the sidebar width. The resized width is persisted in localStorage.
Type: boolean
Default: false
sidebarResizer: true,docHistory
Enables per-document git revision history viewer. When true, each doc page shows a History button that opens a side panel with the document's git commit history and a line-by-line diff viewer for comparing revisions.
In dev mode, history is served by the standalone @takazudo/zudo-doc-history-server package running on port 4322. In production, a CLI generator creates static JSON files during CI. See the Doc History Server reference for details on the server and CLI.
Default: false (set to true to enable)
Tip
See the Document History guide for usage details, keyboard shortcuts, and technical information.
bodyFootUtilArea
Controls which utility items appear in the bottom-of-body action area on every doc page. Set to false to hide the area entirely.
Type: BodyFootUtilAreaConfig | false
Default: false
| Property | Type | Description |
|---|---|---|
docHistory | boolean (optional) | Show the History button (requires docHistory: true) |
viewSourceLink | boolean (optional) | Show a link to the raw source file (requires editUrl) |
bodyFootUtilArea: {
docHistory: true,
viewSourceLink: true,
},
// or hide entirely:
bodyFootUtilArea: false,tocMinDepth
Minimum heading depth included in the table of contents (restriction-only: 2–4, default 2). Raise to 3 or 4 to hide shallower headings from the TOC. Cannot go below 2 (h1 is always the page title) or above tocMaxDepth.
Type: number
Default: 2
tocMinDepth: 3, // hide h2 headings from the TOCtocMaxDepth
Maximum heading depth included in the table of contents (restriction-only: 2–4, default 4). Lower to 2 or 3 to hide deeper headings from the TOC. Cannot exceed 4 or go below tocMinDepth.
Type: number
Default: 4
tocMaxDepth: 3, // hide h4 headings from the TOCheadingIdStrategy
Controls how heading anchor IDs are generated.
"flat"(zfb default) — github-slugger slugs with one dedup counter shared across h2–h6 (e.g.,overview,overview-1)."hierarchical"— each heading's slug is prefixed with its ancestor chain (e.g.,## Foo/### Bar→foo,foo-bar), deduped on the full path so anchors collide far less often.
Switching from "flat" to "hierarchical" is anchor-breaking for existing deep links to nested headings.
Type: "flat" | "hierarchical"
Default: "hierarchical"
headingIdStrategy: "flat",htmlPreview
Global configuration for the <HtmlPreview> component. When set, the provided head, css, and js are injected into every <HtmlPreview> iframe on the site — useful for loading shared fonts, a design system stylesheet, or utility scripts without repeating them on each component demo.
Set to undefined (the default) to disable global injection.
Type: HtmlPreviewConfig | undefined
Default: undefined
The HtmlPreviewConfig object accepts:
| Property | Type | Description |
|---|---|---|
head | string (optional) | Raw HTML injected into <head> (e.g., <link> tags for fonts or icon libraries) |
css | string (optional) | CSS injected as a <style> block after preflight reset |
js | string (optional) | JavaScript injected as a <script> block before </body> |
htmlPreview: {
head: `<link rel="stylesheet" href="https://example.com/design-system.css">`,
css: `body { font-family: sans-serif; }`,
js: `console.log("HtmlPreview loaded")`,
},
// or disable global injection:
htmlPreview: undefined,Tip
Individual <HtmlPreview> blocks can extend the global config by passing their own head, css, or js props — they are appended to the global values, not replaced.
claudeResources
Configures the Claude Code Resources Viewer, which auto-generates documentation pages from your .claude/ directory. Set to false to disable.
| Property | Type | Description |
|---|---|---|
claudeDir | string | Path to the .claude directory (relative to project root) |
projectRoot | string (optional) | Project root override for monorepo setups |
claudeResources: {
claudeDir: ".claude",
},
// or disable:
claudeResources: false,Tip
See the Claude Resources guide for details on what gets generated and how it works.
footer
Configures the site footer. When set to a FooterConfig object, renders a footer with link columns and optional copyright text. Set to false to disable the footer entirely.
Type: FooterConfig | false
Default: false
The FooterConfig object accepts:
| Property | Type | Description |
|---|---|---|
links | FooterLinkColumn[] | Array of link columns displayed in the footer |
copyright | string (optional) | Copyright text shown at the bottom. HTML is supported |
Each FooterLinkColumn:
| Property | Type | Description |
|---|---|---|
title | string | Column heading |
items | FooterLinkItem[] | Array of links in this column |
locales | Record (optional) | Per-locale title overrides (e.g., { ja: { title: "ドキュメント" } }) |
Each FooterLinkItem:
| Property | Type | Description |
|---|---|---|
label | string | Link display text |
href | string | Link URL |
locales | Record (optional) | Per-locale label overrides (e.g., { ja: { label: "はじめに" } }) |
footer: {
links: [
{
title: "Docs",
locales: { ja: { title: "ドキュメント" } },
items: [
{ label: "Getting Started", href: "/docs/getting-started", locales: { ja: { label: "はじめに" } } },
],
},
{
title: "Community",
items: [{ label: "GitHub", href: "https://github.com/my-org/my-repo" }],
},
],
copyright: `Copyright © ${new Date().getFullYear()} Your Name.`,
},
// or disable footer:
footer: false,headerNav
An array of navigation links rendered in the site header bar. Each item supports the following properties:
| Property | Type | Description |
|---|---|---|
label | string | Display text shown in the header |
labelKey | string (optional) | i18n translation key (e.g., "nav.gettingStarted") — overrides label when a translation is available |
path | string | URL path the link navigates to |
categoryMatch | string (optional) | Links this header tab to a sidebar category. When active, only the matched category's sidebar is shown |
headerNav: [
{ label: "Getting Started", labelKey: "nav.gettingStarted", path: "/docs/getting-started", categoryMatch: "getting-started" },
{ label: "Guides", labelKey: "nav.guides", path: "/docs/guides", categoryMatch: "guides" },
{ label: "Reference", labelKey: "nav.reference", path: "/docs/reference", categoryMatch: "reference" },
{ label: "Claude", labelKey: "nav.claude", path: "/docs/claude", categoryMatch: "claude" },
],headerRightItems
Controls the items rendered in the right side of the site header, in order. Each item is a discriminated union on the type field.
Type: HeaderRightItem[]
type | Additional fields | Description |
|---|---|---|
"component" | component — one of "theme-toggle", "language-switcher", "version-switcher", "github-link", "search" | Renders a built-in header component |
"trigger" | trigger — one of "design-token-panel", "ai-chat" | Renders a button that opens a panel (requires the matching feature to be enabled) |
"link" | href (string), label? (string), ariaLabel? (string), icon? ("github") | Renders a custom link |
"html" | html (string) | Renders raw HTML |
headerRightItems: [
{ type: "component", component: "version-switcher" },
{ type: "trigger", trigger: "design-token-panel" },
{ type: "trigger", trigger: "ai-chat" },
{ type: "component", component: "github-link" },
{ type: "component", component: "theme-toggle" },
{ type: "component", component: "search" },
{ type: "component", component: "language-switcher" },
// custom external link:
{ type: "link", href: "https://example.com", label: "Blog", ariaLabel: "Blog" },
],zfb Configuration
The root zfb.config.ts controls the build pipeline:
export default defineConfig({
framework: "preact",
tailwind: { enabled: true },
collections, // derived from settings.docsDir + settings.locales
adapter: "@takazudo/zfb-adapter-cloudflare",
plugins: integrationPlugins, // doc-history / search-index / llms-txt / claude-resources
});Key aspects:
framework: Preact — every component is a
.tsxfile (server-rendered by default; client islands hydrate via zfb's runtime)tailwind: First-class Tailwind CSS v4 integration
collections: Generated from
settings.docsDirandsettings.locales, validated by zod schemas defined in the same fileadapter: Cloudflare Workers — wraps the SSR bundle into
dist/, required for any route exporting_ worker. js prerender = falseplugins: Each integration (doc-history, search-index, llms-txt, claude-resources) is a small wrapper module under
.whose default export is a/ plugins/ ZfbPlugini18n routing: English (default at
/) and additional locales declared indocs/ . . . settings.locales. Default locale has no URL prefixBuild-time highlighting: Powered by syntect (zfb's Rust pipeline) with a single fixed theme (
base16-ocean-dark); not derived fromcolorScheme
Logo
The site logo is displayed on the landing page as a full-color banner image. The file is located at public/.
The default banner is a 1200×630 SVG with the background baked in, so it renders correctly on both light and dark themes without any CSS masking. To update the logo, replace public/ with your own SVG file.
Because the banner is rendered as a plain <img> element, there are no constraints on background color or alpha channel — any SVG will display as-is.
Color Scheme Config
Color schemes are defined in src/. Each scheme provides 21 color properties:
background,foreground,cursor,selectionBg,selectionFgpalette— 16 color slots (palette[0]throughpalette[15])semantic(optional) — overrides forsurface,muted,accent,accentHover, and more
Info
For details on adding or customizing color schemes, see the Color guide.