Skip to content

Migrate docs site from MkDocs/Material to Zensical #10

Description

@ClaydeCode

Summary

Replace MkDocs + Material for MkDocs with Zensical as the generator for docs.freeshard.net.

Blocked by #4 (move the blog to the Astro landing page). Zensical does not support the Material blog plugin yet (zensical/backlog#30, open, no activity since 2025-11-13). Once #4 lands and the blog plugin is dropped from mkdocs.yml, this repo has zero unsupported plugins and the migration is unblocked — no need to wait on backlog#30.

Why

  • MkDocs 1.x is unmaintained (no release in ~2 years).
  • MkDocs 2.0 is not an upgrade path: no plugin system, TOML config, no migration path, and explicitly incompatible with Material for MkDocs.
  • Material for MkDocs has been in maintenance mode since 2025-11-06, with 12 months of critical bug/security fixes guaranteed (so through roughly November 2026).
  • Zensical is the successor by the same author, MIT-licensed, and reads mkdocs.yml natively.

Not urgent — this is a static site generator, so an unpatched build chain is not a live attack surface. But the stack should not stay frozen indefinitely.

Compatibility check (done 2026-07-25)

Trial-built this repo with uvx --with markdown-include zensical build (Zensical 0.0.51) against a scratch copy and diffed the HTML against the MkDocs output:

Feature Result
mkdocs.yml read natively, site_dir: public respected works, build in 1.7s
mkdocs-glightbox compatibility shim (zensical/backlog#21 closed 2026-04-23)
markdown-include identical expansion (fs.all_app_data occurrences: 2 vs 2)
Mermaid via pymdownx.superfences class="mermaid" emitted, loader in Zensical's JS bundle
Emoji (twemoji) renders
extra.status icons identical (md-status occurrences: 6 vs 6)
nav tabs, palette toggle, social links, search all present
Material blog plugin not supported — see blocker above

Side effect worth keeping: Zensical reports missing anchors as build warnings. It found a broken link in a 2023 blog post that mkdocs build --strict never flagged (MkDocs only logs those at INFO). Fixed in #9.

Sequencing

Order matters. Doing the swap before the blog has moved would silently break the blog: Zensical renders posts at /blog/posts/<dir>/main/ instead of Material's /blog/YYYY/MM/DD/<slug>/, and the archive index comes out empty.

  1. Move blog onto freeshard.net via Astro content collections (from docs MkDocs) #4 ships: blog live on freeshard.net, 301 redirects in place.
  2. Remove blog from the plugins: list in mkdocs.yml, delete docs/blog/.
  3. This issue: swap the generator.

Scope

  • Re-run the trial build against the post-Move blog onto freeshard.net via Astro content collections (from docs MkDocs) #4 tree; diff the generated HTML against the MkDocs output page by page.
  • Visual pass: Mermaid diagrams, dark mode, code blocks with line numbers and annotations, glightbox image zoom.
  • Replace mkdocs/mkdocs-material in requirements.txt with zensical (keep markdown-include; mkdocs-glightbox can go, Zensical handles it natively).
  • Swap the build command in .github/workflows/ci.yml (mkdocs build --strictzensical build) and confirm it still emits to public/.
  • Keep mkdocs.yml as-is initially — Zensical reads it. Converting to zensical.toml is optional and can wait for the announced migration tool.
  • Update agents.md (tech stack, commands, deployment).

Risks

  • Zensical is 0.0.x alpha and iterating fast — pin the version in requirements.txt.
  • No multi-version docs support yet. We do not use versioning, so this does not affect us.
  • Theme overrides would need rethinking under Zensical's theming model. We have none active (custom_dir is commented out; docs/css/extra.css is small), so this is cheap for us.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions