/CLAUDE.md
CLAUDE.md at /CLAUDE.md
Path: CLAUDE.md
Documentation Site (zudo-doc)
Built with zudo-doc 5.x on zfb (@takazudo/): single config file, Japanese default locale, no i18n, light/dark color mode (default dark). The project is intentionally minimal — layout, chrome, islands, routes, and design tokens all ship from @takazudo/zudo-doc in node_modules; the project holds only its config, content, and public assets.
Structure
zfb.config.ts— THE one config file:defineConfig({ ...zudoDoc({ …diff-from-defaults fields }) }). There is nosrc/(retired with the 1.x preset shape in the 4.x rescaffold).config/ settings. ts src/— documentation pagescontent/ docs/ <category>/ <page>. mdx src/— Tailwind layer setup + package CSS imports + an (empty)styles/ global. css @themeoverride block. Design tokens ship from@takazudo/; only genuine overrides belong here.zudo- doc/ theme. css pages/— 1-line re-export of the package home routeindex. tsx pages/docs/[[...slug]].tsx— self-contained, host-owned doc-route seam retained alongside zfb 2.15.1's injected dynamic route (package-owned routes cover everything else: 404, sitemap, robots)public/img/— static assets (logo)
Development
pnpm --filter doc build # Production build (served at /doc/)
pnpm --filter doc exec zfb dev # Dev server (port 4321)
pnpm --filter doc check # zfb check (collections + tsc)Build Output Shape (base: "/")
zfb build emits to dist/:
dist/docs/— rendered page HTML (served at https:/ )/ doc. zudo- text. app/ docs/ dist/assets/— CSS/JS bundles (served at /doc/assets/)dist/img/— public images, copied flat (served at /img/)dist/favicon.{svg,ico},dist/favicon-{16x16,32x32}.png— flat-copied frompublic/. zudo-doc 5.x emits<link rel=icon>tags for all four, so removing any of them produces a 404 on every page. All four carry the zudo-text mark — the fish sub-path ofpublic/on a light rounded plate (#4695). Regenerate the raster three fromimg/ logo. svg public/if the mark ever changes;favicon. svg favicon.icomust stay a multi-size container (16/32/48)dist/,index. html dist/— root pages; plus package-route extras (404. html sitemap.xml,robots.txt,search-index.json,theme-packs/,__zfb/)All HTML
href/srcattributes are root-relative (/,assets/ … /)docs/ …
Deployment: this site owns its own Cloudflare Pages project (zudo-text-doc), deployed by . and served at https:zudo-text-preview artifact, and the old / path is not redirected — pre-release, no external users, nothing to preserve.
Why its own project: zfb bakes base into every emitted URL and gives no way to vary it per build — no --base flag, no env var, and zfb.config.ts is evaluated in an embedded V8 where process is undefined. A single content tree can serve / or /, never both. Owning a project also restores per-PR previews (pr-N.zudo-text-doc.pages.dev), which is what the shared artifact used to provide.
copyPublicWithBase is gone with the prefix — at base / there is no segment to prefix, so public/ lands flat either way.
Content Conventions
All docs use
.mdxextension with YAML frontmatter (title,sidebar_position)Sidebar is auto-generated from filesystem —
sidebar_positioncontrols orderingCategories map to
headerNaventries inzfb.config.tsviacategoryMatchGenerated claude-resources docs (
claude/,claude-md/,claude-commands/,claude-skills/,claude-agents/) are gitignored — regenerated on each dev/buildHeading IDs are hierarchical (since zudo-doc 4.x; the 1.x
flatstrategy is gone): an in-content anchor is#<parent-heading-path>-<own-slug>, e.g.#2-provider-contract-2e-optional-layouts. When linking to a heading, copy the id from the built HTML rather than guessing the flat slug.zfb buildwarns on broken in-page anchors — treat those warnings as errors. zfb 2.3.0 and later also validate cross-file.mdx#fragmentlinks that surviveresolveMarkdownLinks, so stale flat slugs that older versions silently accepted now surface as warnings.
Admonitions require a blank line after the opening fence
zfb's Rust directive parser requires a blank line between a :::name admonition fence (:::note, :::tip, :::info, :::warning, :::danger, :::caution, including the :::name[Custom Title] form) and its content. This is a hard parser requirement, not a style choice.
Omitting it does not merely drop that one admonition — the first content line is swallowed, the block fails to close, and the breakage cascades: the following heading and the next admonition get pulled into the broken block and corrupted. Always leave a blank line after the opening fence (and, by the established convention in this repo, before the closing :::):
:::note
Body text goes here.
:::The zudo-doc site renders only admonitions from the directive family. (:::steps, :::card, :::figure, etc. documented in manual/ are the app preview-pane directives, rendered by a different renderer.)