zudo-doc-writing-rules
Doc-writing rules for zudo-doc content (mdx files under src/content/docs/ and src/content/docs-ja/). Consult before writing or editing doc content. Covers: no h1 in content, sidebar_position is mandat...
zudo-doc Doc-Writing Rules
IMPORTANT: Consult these rules before writing or editing any mdx content under src/ or src/. These rules exist to prevent common AI mistakes that silently break layout, navigation, or i18n.
Reference
For navigation structure rules (which category, filesystem layout), see the companion skill zudo-doc-navigation-design. This skill covers content-level mistakes, not structural ones.
Hard Rules (never violate)
No h1 in content
Frontmatter
titleis the page h1. It is rendered automatically by the doc layout.Content MUST start with
## h2, not# h1.Writing
# Somethinginside the body produces a duplicate h1 and breaks heading hierarchy / TOC / a11y.
---
title: Installation
sidebar_position: 1
---
## Prerequisites ← start here, NOT with a "# Installation" heading
...Do not use horizontal rules as section separators
Headings and whitespace already express document structure; do not add body-level
---merely to divide sections.Use a horizontal rule only when the rule itself has semantic meaning, such as documentation that demonstrates horizontal-rule syntax.
Always set sidebar_position
Without it, pages sort alphabetically within their category — almost never what you want.
Set it in the frontmatter of every page, including category
index.mdxfiles (which control the category's position in the parent sidebar).Small integers are fine; leaving gaps (1, 2, 3, 10) makes later insertion easier.
Kebab-case file names
my-article.mdx✓myArticle.mdx✗ — breaks on case-sensitive filesystemsmy_article.mdx✗ — inconsistent with the rest of the site
The URL slug is derived from the filename, so kebab-case also keeps URLs clean.
Bilingual rule
When creating or updating any doc page, update both EN (
src/) and JA (content/ docs/ src/) versions.content/ docs- ja/ Keep code blocks identical — only translate prose.
Keep
<HtmlPreview>and other JSX blocks identical.The JA directory should mirror the EN directory tree exactly.
Exception: pages with
generated: truein frontmatter are skipped (they are generated at build time).Exception: pages whose paths fall under
settings.defaultLocaleOnlyPrefixesare default-locale-only by design — do NOT create a JA mirror for them. The source of truth issettings.defaultLocaleOnlyPrefixesinsrc/. Current entries:config/ settings. ts /,docs/ claude- md/ /,docs/ claude- skills/ /,docs/ claude- agents/ /. The top-leveldocs/ claude- commands/ /index is bilingual — only the four deep prefixes above are default-locale-only.docs/ claude/
Frontmatter Schema
The schema is package-owned (@takazudo/, source packages/ — the default buildDocsSchema, wired in via zudoDoc(); there is no more host src/). Zod validation. Required and key optional fields:
| Field | Type | Required? | Notes |
|---|---|---|---|
title | string | yes | Renders as page h1 |
sidebar_position | number | recommended | Without it, pages sort alphabetically |
description | string | no | Subtitle below the h1 |
sidebar_label | string | no | Overrides title in the sidebar only |
tags | string[] | no | Cross-category grouping |
draft | boolean | no | Excludes the page from the build entirely |
unlisted | boolean | no | Built but hidden from sidebar/nav |
generated | boolean | no | Build-time generated; skip JA translation |
hide_sidebar | boolean | no | Hide the left sidebar on this page |
hide_toc | boolean | no | Hide the right-side table of contents |
The schema ends with .passthrough(), so custom keys (e.g. author, status) are preserved rather than rejected — they simply carry no built-in behavior. Consequence: a typo in a framework field name (sidebar_postion) does NOT error at build time; double-check spellings against the table above.
Linking Between Docs
Use relative paths with the .mdx extension. The framework's link resolver rewrites them to the correct URLs at build time and validates them.
[Link text](./sibling-page.mdx)
[Link text](../other-category/page.mdx#anchor)Do NOT use absolute paths like
/in prose — the resolver cannot verify them.docs/ foo/ bar Do NOT omit the
.mdxextension — the resolver needs it to find the target.
For the companion skill that audits links: /.
Admonitions
Admonitions are available globally — no imports needed.
Directive syntax (preferred in prose-heavy content):
:::note[Optional Title]
Body content.
:::JSX syntax (preferred when nesting other JSX):
<Note title="Optional Title">Body content.</Note>
<Tip>...</Tip>
<Info>...</Info>
<Warning>...</Warning>
<Danger>...</Danger>
<Caution>...</Caution>All admonition components accept an optional title prop. (caution is danger-adjacent, used by GitHub-style [!CAUTION] alerts; JSX additionally registers <Important> for [!IMPORTANT].)
Common Mistakes (Do Not Do)
Starting content with
# Foo— duplicates the h1. Start with## Foo.Adding
---between headed sections — headings and whitespace already provide the separation.Forgetting
sidebar_position— produces alphabetical chaos in the sidebar.camelCase or PascalCase file names — breaks on some filesystems.
Updating only the EN or only the JA version — breaks the bilingual mirror (except for pages under
defaultLocaleOnlyPrefixesor withgenerated: true).Absolute
/links in prose — the resolver cannot verify them; use relativedocs/ . . . .instead./ page. mdx Omitting the
.mdxextension in links — the resolver requires it.Misspelling framework frontmatter fields — the schema passes unknown keys through, so a typo'd
sidebar_positionsilently does nothing instead of erroring.Translating code inside code blocks — the bilingual rule says code stays identical.
Recommended Workflow
Decide where the page belongs (see
zudo-doc-navigation-designfor the category decision).Create the EN file under
src/withcontent/ docs/ <category>/ <page>. mdx titleandsidebar_position.Write content starting with
## h2headings only.Use
.relative links with/ .mdxextension for cross-refs.Create the matching JA file under
src/— same code blocks, translated prose.content/ docs- ja/ <category>/ <page>. mdx Run
pnpm formatthenpnpm buildto verify — the build will catch missing required fields, broken links, and unknown frontmatter.