Skip to content

chore: migrate the docs build from MkDocs to Zensical - #262

Merged
Naruto merged 1 commit into
developfrom
chore/migrate-to-zensical
Aug 7, 2026
Merged

chore: migrate the docs build from MkDocs to Zensical#262
Naruto merged 1 commit into
developfrom
chore/migrate-to-zensical

Conversation

@Naruto

@Naruto Naruto commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

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.yml everything shared by both locales
mkdocs.yml English → site/
mkdocs.ja.yml Japanese → site/ja/

Both plugins go away: mkdocs-static-i18n is what the split replaces, and Zensical parses the > [!NOTE] callout syntax natively, so mkdocs-callouts is no longer needed. nav_translations is replaced by a nav per 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 (INHERIT concatenates sequences instead of replacing them; page.is_homepage is never set; site_url must be per locale; a shared docs/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-i18n rewrote 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 emits alt.link as written, so from /workflow/usage_basic/ the Japanese link pointed at /ja/. overrides/partials/alternate.html now derives the href from page.url, reproducing the plugin's output exactly:

en page /workflow/usage_basic/  ->  ja: ../../ja/workflow/usage_basic/
ja page                         ->  en: ../../../workflow/usage_basic/

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's site_meta block, 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 src like 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 in AGENTS.md.

3. 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 in setup/build.md was 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 both docs_dirs once the build is split, and Zensical does not follow symlinks inside docs_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] styling

Not a built-in admonition type, so Zensical would render it with the generic fallback. mkdocs-callouts used to map it onto tip; docs/*/stylesheets/extra.css reproduces 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

  • Both locales build clean from a fresh venv installed off docs/requirements.txt.
  • All 28 pages render byte-identical content to the MkDocs build.
  • All 140 asset references resolve in both locales — they did not before (14 were broken).
  • strict: true still exits 1 on a broken link. serve validates nothing in Zensical (serve --strict is accepted and does nothing), which AGENTS.md now says.

Reviewer notes

  • Build order matters. English clears site/, which contains site/ja, so it must run first. pages.yml does this and says why.
  • Docs still have no PR build (pages.yml is release: published + dispatch, pr.yml builds the extension), so the local build remains the only gate — and both locales have to be built.

🤖 Generated with Claude Code

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
Naruto force-pushed the chore/migrate-to-zensical branch from 5998419 to a479d1c Compare August 7, 2026 03:20
@Naruto
Naruto merged commit b146bc3 into develop Aug 7, 2026
0 of 2 checks passed
@Naruto
Naruto deleted the chore/migrate-to-zensical branch August 7, 2026 03:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant