Guide

Version API documentation

DocsPress can publish several API documentation versions from one repository into one WordPress site. Versioning is opt-in: without versions-file, collection, synchronization, URLs, and reverse pull requests behave exactly as before.

Run the versioning example →

The example starts on a historical v1 Page so the version switcher and outdated-version notice are visible immediately. It also seeds v3 from root files, v2 from a directory, v1 from filename suffixes, missing counterparts, version metadata, and the Pages-screen filters.

Historical v1 documentation with the version dropdown in the header and a full-width notice linking to v3
The historical Page keeps its version-aware navigation while making the latest documentation one click away.

Configure the version registry

Add a repository-relative JSON file and pass it to the Action. DocsPress uses the registry throughout collection, synchronization, public routing, and reverse pull requests.

  1. Declare ordered releases

    Name the repository latest version and map every active release to a root, directory, suffix, or manifest source.

  2. Synchronize version data

    DocsPress validates ownership, creates or updates version terms, then builds each release as a separate managed Page tree.

  3. Serve the selected release

    WordPress exposes the effective latest at clean URLs and historical releases below stable version prefixes.

yaml .github/workflows/sync-docs.yml
- uses: Automattic/docspress@main  with:    wordpress-site: example.wordpress.com    wordpress-access-token: ${{ secrets.WP_ACCESS_TOKEN }}    docs-dir: docs    versions-file: docs-versions.json    status: draft    delete-mode: trash    dry-run: true
Point the Action at the ordered version registry. Start with a draft dry run before publishing.
json docs-versions.json
{  "latest": "v3",  "versions": [    {      "id": "v3",      "label": "v3",      "source": { "type": "root" }    },    {      "id": "v2",      "label": "v2",      "source": { "type": "directory", "path": "v2" }    },    {      "id": "v1",      "label": "v1",      "source": { "type": "suffix", "suffix": ".v1" }    }  ]}
Order controls the WordPress administration view and version switcher.

Entries are ordered for WordPress administration and the version switcher. IDs are lowercase URL-safe slugs. latest must name an entry. If a root source exists, it must be the repository latest version.

Reference

Version registry fields

The registry is deliberately small; source-specific values are required only by the selected layout.
7 fields
latest string required
Version ID treated as the repository default latest release.
versions[].id string required
Lowercase URL-safe version identifier used in taxonomy terms and historical routes.
versions[].label string
Reader-facing label. The ID is used when the label is omitted.
versions[].source.type enum required
How this version owns Markdown files.
versions[].source.path string
Directory below docs-dir or repository-relative manifest path, depending on the source type.
versions[].source.suffix string
Filename marker removed before logical routes are calculated.
versions[].redirects string
Repository-relative redirect manifest scoped to this version.

Supported source layouts

The layouts can coexist. This example keeps the current v3 files at the root of docs/, v2 in a directory, and v1 in filename suffixes:

repository/ File tree
  • docs-versions.json
  • docs/
    • hello.md
    • authentication/
      • oauth.md
      • api-keys.v1.md
    • v2/
      • hello.md
      • authentication/
        • api-keys.md
One registry can collect root, directory, and filename-suffix sources without moving every release into the same convention.
v3 source
{  "id": "v3",  "label": "v3",  "source": { "type": "root" }}
Choose the source contract that matches each existing release.

Root latest

Root discovery uses unclaimed Markdown below docs-dir. Files claimed by a directory, suffix, or manifest version are excluded:

plaintext Collected v3 routes
docs/hello.md                     -> v3 /hellodocs/authentication/oauth.md      -> v3 /authentication/oauth
Unclaimed root Markdown belongs to the registry latest version.

Root Markdown belongs to the configured latest ID. DocsPress does not create a separate Current term.

Version directories

Directory paths are relative to docs-dir:

plaintext Collected v2 routes
docs/v2/hello.md                       -> v2 /hellodocs/v2/authentication/api-keys.md     -> v2 /authentication/api-keys
The directory prefix identifies the version and is removed from its logical routes.

Filename suffixes

The suffix is removed before the logical route is calculated:

plaintext Collected v1 routes
docs/hello.v1.md                       -> v1 /hellodocs/authentication/api-keys.v1.md     -> v1 /authentication/api-keys
The suffix marks ownership without adding a public path segment to the logical route.

Per-version manifests and redirects

A manifest path is repository-relative. Its Markdown sources are resolved relative to the manifest, exactly like the normal manifest-file format:

Redirect entries use logical routes within that version. A redirect from old to hello in v1 points to /docs/v1/hello/, not to the same route in another version.

WordPress data and administration

The DocsPress Blocks plugin is required when versions-file is enabled. Synchronization creates a REST-visible docspress_version taxonomy on Pages. Version terms record order, active state, repository-default latest, and effective latest; managed Pages retain the fields needed for routing and exact reverse synchronization.

Reference

Managed Page version data

Synchronization owns these REST-visible Page fields and repairs drift even when visible content is unchanged.
6 fields
_docspress_version_id string required
Taxonomy-aligned version ID for this Page.
_docspress_logical_route string required
Route shared by counterpart Pages across versions.
_docspress_page_identity string required
Stable identity combining version and logical route.
_docspress_source_type enum required
Source layout that owns the Page.
_docspress_source_path string required
Exact Markdown destination used for reverse synchronization.
_docspress_docs_root string required
Managed documentation root used to isolate routes and lookups.
Sequence

Version data stays attached through both directions

4 relationships
The version ID and exact source path remain authoritative instead of being inferred from a same-route Page.

Removed versions become inactive instead of losing their taxonomy history. Pages follow delete-mode.

Pages remain stored below stable internal parents such as /docs/v1/authentication/api-keys/. On Pages → All Pages, the Docs version column is sortable, labels filter the list, Latest and Inactive states are visible, and the ordered dropdown includes All versions, Latest, and every known version with counts. When synchronized Pages include GitHub metadata, a GitHub path column links each exact repository-relative Markdown path to its configured repository and ref in a new tab; virtual containers and unrelated Pages display a dash. Managed Page assignment is read-only because synchronization owns it.

WordPress Pages administration showing version filters, version-specific Page hierarchies, latest badges, and exact GitHub source paths
Filter the Pages table by version and follow an exact Markdown source path without mixing version trees.

Use Settings → DocsPress to inspect the repository default and effective latest. An active administrator override wins; an invalid or inactive override falls back to the repository default. Changing the override updates routing immediately without renaming Pages.

DocsPress version settings showing v3 as the repository default and effective latest with no administrator override
The repository default remains visible beside the effective latest version and optional site override.

Public routes

The effective latest version uses clean URLs while historical versions retain their version prefix:

v3 public routes
/docs/hello//docs/authentication/oauth/
Changing the effective latest updates public routing without renaming the stable internal Page trees.

The effective latest’s explicit prefix permanently redirects to the clean route. Canonical Page links, navigation, breadcrumbs, search, adjacent navigation, XML sitemaps, .md responses, and llms.txt use the same version context. llms.txt indexes the effective latest tree; historical .md URLs remain directly addressable.

The switcher matches Pages by logical route. If the selected version has no counterpart, it links to that version’s root and announces that the requested Page is unavailable.

Neutral
Missing counterparts stay inside the selected version

The switcher never substitutes a same-route Page from another release. It opens the selected version root and exposes the unavailable-page state to the reader.

Version-safe fallback

Version interface blocks

The bundled Header template places a compact Version Switcher dropdown immediately before Command Search. The Page template places the historical-version notice as a full-width status bar directly below the Header. They remain independent Site Editor blocks, so a site owner can move, remove, or restyle either one.

Customize the header switcher

Open Appearance → Editor → Design → Templates → Pages, select the Header, and choose Edit original. Select Version Switcher to configure its label, presentation, badges, single-version behavior, and missing-page wording. The block can remain immediately before Command Search or move anywhere the Header layout allows.

Site Editor Header template part with the Version Switcher selected and its settings visible
Configure the dropdown in context while retaining native Header layout controls.

docspress/version-switcher supports:

  • label text and visibility;
  • select-menu or link-list presentation;
  • latest badge visibility;
  • hiding when only one version exists;
  • missing-page wording.

Customize the historical-version notice

Return to the Pages template and select Version Notice to edit its message, latest-link label, icon, and dismissibility. The preview uses example version data so the bar remains editable even when the current Page is the latest version.

Site Editor Pages template with the full-width Version Notice selected and its message, link, icon, and dismissibility controls visible
Edit the historical-version message while previewing its full-width placement below the Header.

docspress/version-notice appears only on historical versions and supports:

  • a message with safe {current} and {latest} placeholders;
  • latest-link label;
  • icon visibility;
  • visitor dismissibility.

The Styles panel for either block exposes native colors and gradients, link color, typography, spacing and block gap, borders and radius, dimensions, sticky positioning, and shadow. Advanced controls include the anchor and custom classes. Full alignment plus the Version Notice block’s header-version-notice class creates the bundled bar; changing its alignment or removing that class returns the notice to its portable card treatment.

Both are API v3 server-rendered blocks. The DocsPress, WordPress.org, WordPress.com, and Jetpack style families provide complete component recipes while semantic theme tokens keep the blocks portable to another block theme.

Developers can customize resolved choices with docspress_version_switcher_choices, the notice text with docspress_version_notice_message, the effective latest ID with docspress_effective_latest_version, and generated destinations with docspress_version_target_url.

Reverse synchronization

The source path stored on each Page is authoritative. WordPress edits return to the exact file:

plaintext Exact reverse-sync destinations
v3 /authentication/oauth  -> docs/authentication/oauth.mdv2 /authentication/api-keys  -> docs/v2/authentication/api-keys.mdv1 /authentication/api-keys  -> docs/authentication/api-keys.v1.md
The owning version determines the destination; matching logical routes in other releases are ignored.

Manifest-backed title changes update the owning manifest. Links are converted only against Pages in their stable version tree, so a v1 edit cannot silently target a same-route v2 file.

DocsPress maintains one rolling docspress/wordpress-sync pull request. One changed version uses docs(v1): sync changes from WordPress; multiple versions use docs(versions): sync N files from WordPress. The body groups exact paths under version headings and identifies the effective latest. pull-request-title remains an explicit override.

Migrating from Docusaurus

Docusaurus stores frozen releases in versioned_docs/version-[name]/, keeps an ordered versions.json, and normally serves its configured latest release at /docs/ while the working docs/ tree can appear at /docs/next/. Its version command copies the current docs tree and sidebar into versioned directories. Docusaurus also recommends file-path Markdown links so the build can resolve them within the correct version. See the Docusaurus versioning guide.

DocsPress can adopt copied Docusaurus trees with directory entries, or keep a repository’s existing suffix/manifests without forcing a copy-based release workflow. The important semantic difference is that DocsPress’s root source is the named repository latest version; a WordPress override can change the public effective latest without changing repository files. If a project needs a separately published unreleased next tree, model it as another explicit version source rather than an unnamed Current term.

Was this helpful?