--- orphan: false --- # Multi-version docs: local preview ```{note} This page documents the **preview** workflow on the `feat/versioned-docs-preview` branch. The full release plan is in [MADDENING/docs/developer_guide/versioned_docs.md](https://microrobotica.org/maddening/developer_guide/versioned_docs.html). The version switcher is **off by default** — CI keeps deploying the single-version site. To preview the multi-version layout locally, opt in with `DOCS_MULTIVERSION=1` (the Makefile targets below do this for you). ``` ## Quick start ```bash cd MICROROBOTICA/docs # One-shot build of every version + serve locally make preview-versions # builds, then runs http.server on :8000 # Open http://localhost:8000/maddening/ in a browser. # The version switcher is in the top navbar. ``` `sphinx-build` must be reachable. The Makefile auto-detects the sibling shared venv (`../../.venv`); otherwise activate your docs venv first (`source ../../.venv/bin/activate`) or pass an explicit `make … SPHINXBUILD=/path/to/sphinx-build`. The output structure mirrors the production target: ``` _build/html/ ├── index.html ← MICROROBOTICA latest ├── _static/switcher.json ← MICROROBOTICA version list ├── sitemap.xml ← MICROROBOTICA sitemap ├── maddening/ │ ├── index.html ← MADDENING latest (= main tip) │ ├── _static/switcher.json ← canonical MADDENING version list │ ├── sitemap.xml ← MADDENING sitemap (latest only) │ ├── v0.1/index.html ← MADDENING v0.1.0 tag │ └── v0.2/index.html ← MADDENING v0.2.0 tag └── mime/ ├── index.html ← MIME latest └── _static/switcher.json ← MIME version list (one entry) ``` Every version's HTML references `/maddening/_static/switcher.json` via a root-relative URL, so v0.1 pages pick up the switcher dropdown even though v0.1's source tree predates the switcher. ## Iterating on docs without committing The default `make all-versions` builds every version from its remote git ref. When you're editing a docs file on the latest line and want to see the change without committing, point the "latest" tier at your local working copy: ```bash make preview-local MADDENING_LOCAL=/home/you/MSF/msf/MADDENING # Edit MADDENING/docs/... files, then re-run — <30 s incremental. ``` Older versions (v0.1, v0.2) still come from git tags — they're frozen and don't need re-builds unless you nuke `_build/`. ## What's running | Knob | Default | Multi-version build | |---|---|---| | `DOCS_MULTIVERSION` env | unset | `1` | | `DOCS_VERSION` env | unset | the build label (`v0.1`, `v0.2`, `latest`) | | `DOCS_DEPLOY_BASE` env | `https://microrobotica.org` | `http://localhost:8000` | | `PROJECT` env | from caller | `maddening` / `mime` / `microrobotica` | | `MULTIPROJECT_PATH_` env | unset → submodule path | tempdir worktree | | navbar shows version switcher | no | yes (rendered, fetches JSON at page-load) | The switcher JSON contract: a flat list of `{version, name, url, preferred}` rows. `version` is the value that `DOCS_VERSION` must match for the theme to highlight the row as "current". `preferred: true` marks the stable release (the one new visitors should land on if they have no preference). ## Canonical URLs and the sitemap Multi-version docs publish the *same* page at several URLs (`/maddening/quickstart.html`, `/maddening/v0.2/quickstart.html`, `/maddening/v0.1/quickstart.html`). To stop search engines treating those as duplicate content, the **latest** version is declared canonical: * `conf.py` sets `html_baseurl` **without** a version segment (`.../maddening/`, never `.../maddening/v0.2/`). Sphinx derives every page's `` from it, so a versioned page emits `` — it canonicalises to the *latest* copy of that page. * The **sitemap is generated by the latest build only**. `conf.py` drops the `sphinx_sitemap` extension when `DOCS_VERSION != latest`, so `/maddening/v0.1/` and `/maddening/v0.2/` ship no `sitemap.xml`. Only `/maddening/sitemap.xml` (latest) exists, and that is the one `seo/sitemap_index.xml` references. * `seo/robots.txt` keeps `Allow: /` — crawlers must be able to reach the versioned pages so they can *see* the canonical link and consolidate. Don't `Disallow` the version subdirs. Net effect: search engines index one copy of each page (the latest), and the version switcher is the only way readers reach older docs. ## Adding a version `MADDENING/docs/_static/switcher.json` is the source of truth for the MADDENING dropdown; `MICROROBOTICA/docs/_static/switcher.json` and `MIME/docs/_static/switcher.json` are the (currently single-entry) lists for the other two. When a project cuts a release: 1. Tag the release in that project's repo (e.g. `v0.3.0`). 2. Add a row to that project's `switcher.json` — `version` is the label, and move `preferred: true` to the new stable release. 3. Update the project's `*_VERSIONS` line in `docs/Makefile`, e.g. `MADDENING_VERSIONS := v0.1:v0.1.0 v0.2:v0.2.0 v0.3:v0.3.0 latest:origin/main`. 4. Rebuild. The `latest` row builds from `origin/main`; the canonical `switcher.json` it ships is whatever is on `main`, so commit the `switcher.json` edit to `main`. ## Cleaning up ```bash make clean # rm -rf _build/ make clean-worktrees # remove /tmp/msf-docs-worktree-* ``` `clean-worktrees` is safe to run anytime — it removes the git worktrees the multi-version build creates under `/tmp/`. Subsequent builds re-create them on demand. ## Knobs that *won't* affect production Everything in this preview is gated on env vars that default to "production single-version": * `make all` (no `-versions` suffix) — unchanged from v0.1 behaviour. * CI workflow (`.github/workflows/docs.yml`) — untouched. * The `docs/conf.py` switcher block is wrapped in `if _multiversion:` so it's a no-op without `DOCS_MULTIVERSION=1`. To actually ship multi-version, the steps are in [MADDENING's `versioned_docs.md`](https://microrobotica.org/maddening/developer_guide/versioned_docs.html) § "Rollout sequence" — three small CI changes once you're ready. ## Troubleshooting **"sphinx-build not found"** — activate the docs venv (`source ../../.venv/bin/activate`) or pass `SPHINXBUILD=/path/to/sphinx-build`. **"projects/maddening submodule missing"** — run `git submodule update --init --recursive`. **"worktree add failed for ... @ origin/..."** — the submodule's local clone hasn't fetched that branch yet. Run `git -C docs/projects/maddening fetch origin --tags` and retry. **"worktree at /tmp/... has no docs/index.md (ref too old?)"** — the ref you're trying to build predates the current docs layout. Drop that row from `MADDENING_VERSIONS` in the Makefile. **Switcher shows nothing in the dropdown** — open the browser DevTools network tab and check that `/maddening/_static/switcher.json` returns 200. It's served from `_build/html/maddening/_static/`; the "latest" build is what writes it. **Switcher shows but the current version isn't highlighted** — the `version` field in `switcher.json` has to match `DOCS_VERSION` exactly. The Makefile sets `DOCS_VERSION` to the LABEL part of the `