Skip to content
Blume
English
Esc
navigateopen⌘Jpreview
On this page

Versioning

Freeze snapshots of your docs per release with a version switcher, canonical-to-latest SEO, version-scoped search, and a version-aware agent surface.

Blume versions your docs the way releases actually work: the latest documentation lives at your content root with clean, unprefixed URLs, and each past version is a frozen snapshot in its own folder. Cut a snapshot when you ship, and Blume wires up the switcher, the “old version” notice, search scoping, SEO, and the agent surface for you. It’s opt-in: without a versions block, nothing changes.

Enable it

Add a versions block naming the current docs and any archived snapshots:

versions: {
  current: { label: "v2.0", badge: "Latest" },
  archived: [
    { id: "v1.0" },
    { id: "v0.9", label: "0.9 (legacy)" },
  ],
}

current labels the unprefixed tree in the switcher (with an optional badge). Each archived entry’s id is both the snapshot’s directory name and its URL segment — ids must start with a letter (v1.0, not 1.0) so they can never collide with numeric ordering prefixes. List archived versions newest first; that order is the switcher order.

Cut a version

When you release, freeze the current docs with one command:

blume version v1.0

This copies your content tree into docs/v1.0/ (existing snapshots excluded), rewrites root-absolute links inside the copy so they stay within the snapshot (/guides/x becomes /v1.0/guides/x, fenced and inline code untouched), and registers the id in blume.config.ts — or prints the entry to paste when your config is shaped in a way it won’t touch. Links to pages that aren’t part of the copied tree — generated API references, remote sources like a changelog — keep pointing at the live pages, since the snapshot has no copy of them. Run blume version with no id to list the configured versions.

Review and commit the new directory like any other content. Restart blume dev to pick it up.

docs/
  index.mdx               ->  /              (latest)
  guides/quickstart.mdx   ->  /guides/quickstart
  v1.0/
    index.mdx             ->  /v1.0          (frozen)
    guides/quickstart.mdx ->  /v1.0/guides/quickstart

Archived means frozen. Future edits belong in the live tree; a snapshot is the docs as they were. Blume leans on that: snapshots keep their own folder meta and translations, blume translate never retranslates them, and a configured explicit sidebar applies only to the current docs — a snapshot’s sidebar always comes from its own files.

The switcher and the notice

With versions configured, the header grows a version dropdown automatically. Switching lands on the same page in the target version when it exists, and on that version’s root when it doesn’t (set switcher.redirect: "root" to always land on the root). If you declare your own kind: "version" selector in navigation.selectors, it replaces the automatic one.

Every archived page also shows a non-dismissible notice with a “Go to latest” link pointing at the page’s live equivalent. Customize or disable it per version:

archived: [
  { id: "v1.0", banner: "These docs cover the 1.x SDK." },
  { id: "v0.9", banner: false },
];

SEO

Old docs are search engines’ favorite trap: the stale page outranks the live one, or both compete. Blume defaults to the answer SEO guides recommend and no other docs framework automates — archived pages stay indexable but declare the latest equivalent as their canonical, so the live page is authoritative while version-only content (a page that no longer exists in the latest docs) remains findable with a self-canonical.

Per version you can pick a different treatment:

archived: [
  { id: "v1.0" }, // canonical → latest (default)
  { id: "v0.9", canonical: "self" }, // every page authoritative
  { id: "v0.8", noindex: true }, // deindexed entirely
];

The sitemap follows suit: archived pages whose canonical points at a live equivalent are left out, noindex versions are left out wholesale, and version-only pages stay listed. A page’s own seo.canonical frontmatter always wins.

The search dialog scopes results to the version being viewed, with an “All versions” toggle (remembered per reader) beside the language one. Cross-version hits name their version on the result row. Orama (the default), FlexSearch, Algolia, and Typesense all honor the scoping — hosted records carry a version facet, with the current docs uploaded as "current" — while Pagefind stays unscoped, matching its locale behavior.

Agents

The agent surface is version-aware — something no other docs framework does:

  • The MCP search_docs and list_pages tools default to the current docs and accept version: an archived id ("v1.0") or "all". get_navigation returns an archived snapshot’s tree on request.
  • llms.txt sections archived versions after the current docs, labeled 1.0 (archived), so an agent reading the index knows which docs are frozen.
  • llms-full.txt stays current-only — the flat dump never interleaves frozen copies of the same page.
  • Raw Markdown mirrors (.md URLs) exist for every version’s pages, as for any route.

With i18n

Versioning composes with internationalization. On disk the version folder is outermost — a snapshot naturally contains its locale folders — while in URLs the locale stays outermost, matching the rest of the site:

docs/
  guides/x.mdx            ->  /guides/x
  fr/guides/x.mdx         ->  /fr/guides/x
  v1.0/
    guides/x.mdx          ->  /v1.0/guides/x
    fr/guides/x.mdx       ->  /fr/v1.0/guides/x

Locale fallback works within each version: an untranslated snapshot page renders the fallback locale’s content at the localized URL, and hreflang alternates group per version. A version id may not collide with a configured locale code — Blume rejects that config outright.

What stays unversioned

Versioning covers the docs content tree. The blog, changelog, API references generated from OpenAPI specs, and custom pages are always current. Two more behaviors worth knowing: header tabs are defined against the current docs, so inside an archived tree the sidebar renders unscoped by tabs; and large sites should note each snapshot is a full copy — content, search index entries, and navigation data all grow per version.

Last updated on August 15, 2026

Was this page helpful?