chore: migrate the docs build from MkDocs to Zensical - #262
Merged
Conversation
Follows SpriteStudio-Docs, which moved first. Material for MkDocs is in
maintenance mode; its authors now ship Zensical.
Zensical has no multi-locale build, so each locale gets its own config:
`mkdocs.base.yml` holds everything shared, `mkdocs.yml` builds English to
`site/` and `mkdocs.ja.yml` builds Japanese to `site/ja/`. Both plugins go
away with it -- `mkdocs-static-i18n` is what the split replaces, and Zensical
parses the `> [!NOTE]` callout syntax natively, so `mkdocs-callouts` is no
longer needed.
Beyond the portal's four traps (INHERIT concatenates sequences rather than
replacing them; `page.is_homepage` is never set; `site_url` has to be per
locale; a shared docs/assets/ stops being copied), this repo hit three more,
because unlike the portal it has real media and real callouts:
- **Per-page language switching had to be rebuilt.** `mkdocs-static-i18n`
rewrote the header selector per page, so switching language kept you on
the page you were reading. Without it the stock partial emits `alt.link`
as written and every reader lands on the other locale's home page.
`overrides/partials/alternate.html` now derives the href from `page.url`,
reproducing the old output exactly and keeping every link relative. The
`<link rel="alternate" hreflang>` tags in `<head>` are a known remaining
gap: they sit inside the theme's `site_meta` block, and overriding that
would mean copying thirty lines Zensical may change under us.
- **Zensical resolves raw HTML `src` like a Markdown link**, relative to the
source file; MkDocs passed it through untouched. With `docs/assets/` moved
under each locale, every reference becomes source-relative `../assets/…`.
This is the one place the MkDocs fallback build now produces wrong paths.
- **A list inside a callout needs a blank `>` line before it.** The native
parser follows CommonMark here where `mkdocs-callouts` did not, so one
four-item list was rendering as literal `- ` text. Fixed in the source, in
both locales, which renders identically under either engine.
`[!IMPORTANT]` is not a built-in admonition type, so it would have lost the
styling `mkdocs-callouts` gave it by mapping it onto `tip`; docs/*/stylesheets/
extra.css restores that rather than restyling content nobody asked to restyle.
Fixes five broken images in the Japanese docs along the way: the `<img>`
fallbacks inside the `<video>` blocks pointed one directory level too high and
had been 404ing. Nothing caught it -- strict mode validates page links, not
media -- and per-locale assets make the paths identical in both languages, so
the class of bug goes with it.
Verified: both locales build clean from a fresh venv, all 28 pages render
byte-identical content to the MkDocs build, and all 140 asset references
resolve in both locales (they did not before). `strict: true` still fails the
build on a broken link.
Naruto
force-pushed
the
chore/migrate-to-zensical
branch
from
August 7, 2026 03:20
5998419 to
a479d1c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follows cri-middleware/SpriteStudio-Docs#23, which moved the portal first. Material for MkDocs is in maintenance mode; its authors now ship Zensical as its successor.
What changed
Zensical has no multi-locale build, so each locale gets its own config:
mkdocs.base.ymlmkdocs.ymlsite/mkdocs.ja.ymlsite/ja/Both plugins go away:
mkdocs-static-i18nis what the split replaces, and Zensical parses the> [!NOTE]callout syntax natively, somkdocs-calloutsis no longer needed.nav_translationsis replaced by anavper locale, with the labels written in the language rather than looked up by their English string.Three traps beyond the ones the portal hit
The portal's four (
INHERITconcatenates sequences instead of replacing them;page.is_homepageis never set;site_urlmust be per locale; a shareddocs/assets/stops being copied) all apply here too. This repo has real media and real callouts, so it hit three more:1. Per-page language switching had to be rebuilt.
mkdocs-static-i18nrewrote the header selector on every page, so switching language kept you on the page you were reading. Nothing does that once the locales are separate builds — the stock partial emitsalt.linkas written, so from/workflow/usage_basic/the Japanese link pointed at/ja/.overrides/partials/alternate.htmlnow derives the href frompage.url, reproducing the plugin's output exactly:Everything stays relative, so the site works under any path prefix. Known remaining gap: the
<link rel="alternate" hreflang>tags in<head>still point at each locale root. They sit inside the theme'ssite_metablock, and overriding that would mean copying thirty lines Zensical may change under us — not worth it for metadata on a site that is not published yet.2. Zensical resolves raw HTML
srclike a Markdown link, relative to the source file; MkDocs passed it through untouched. With the media moved under each locale, every reference becomes source-relative../assets/…. This is the one place where the MkDocs fallback build now produces wrong paths, and it is called out inAGENTS.md.3. A list inside a callout needs a blank
>line before it. The native parser follows CommonMark here wheremkdocs-calloutsdid not, so one four-item list insetup/build.mdwas rendering as literal-text. Fixed in the source in both locales — it renders identically under either engine.Fixes 5 broken images in the Japanese docs
Pre-existing, unrelated to the engine. The
<img>fallbacks inside the<video>blocks were written../../assets/…while the<source>next to them used../../../assets/…, so the fallbacks had been 404ing. Nothing caught it — strict mode validates page links, not media. Per-locale assets make the paths identical in both languages, so the whole class of bug goes away.On duplicating 24 MB of media
docs/assets/sits outside bothdocs_dirs once the build is split, and Zensical does not follow symlinks insidedocs_dir(MkDocs does) — it skips them silently, with no warning. So the screenshots and videos are duplicated per locale. Git stores identical content once, so this costs working-tree space, not history, and it is what makes the reference paths uniform across locales. It also leaves room for genuinely localized screenshots later.[!IMPORTANT]stylingNot a built-in admonition type, so Zensical would render it with the generic fallback.
mkdocs-calloutsused to map it ontotip;docs/*/stylesheets/extra.cssreproduces that appearance rather than restyling content nobody asked to restyle. Giving it a colour of its own is an easy follow-up if wanted.Verification
docs/requirements.txt.strict: truestill exits 1 on a broken link.servevalidates nothing in Zensical (serve --strictis accepted and does nothing), whichAGENTS.mdnow says.Reviewer notes
site/, which containssite/ja, so it must run first.pages.ymldoes this and says why.pages.ymlisrelease: published+ dispatch,pr.ymlbuilds the extension), so the local build remains the only gate — and both locales have to be built.🤖 Generated with Claude Code