Versioning
Stardust supports versioned documentation, allowing you to maintain docs for multiple releases simultaneously. Each version is built independently and Stardust renders a version dropdown and optional warning banner.
How It Works
Run one command and Stardust builds every version into its own path prefix:
stardust build --all-versions
For each entry in versions.list it builds that version's content into the
entry's path (e.g. /v1/), prefixes every URL and the search index
accordingly, and adds <meta name="robots" content="noindex, follow"> to every
version except versions.current so search engines only rank the latest docs.
Those noindex versions are also left out of sitemap.xml — only the current
version is listed, so crawlers are never handed URLs they are told not to index.
robots.txt is written once at the site root (never per version, since crawlers
only read it from the origin root) and points at the current version's sitemap.
Each version's content comes from its source directory; an entry without a
source builds from the live content.dir. A single deploy directory contains
all versions — no external merge step.
If you prefer to orchestrate builds yourself (one
stardust buildper branch, merged in CI), the manual workflow below still works — the config is identical, you just skip--all-versions.
Configuration
Add a versions section to your stardust.yaml:
versions:
enabled: true
current: "2.0"
dropdown: true
list:
- version: "2.0"
label: "v2.0 (Latest)"
path: /v2/
- version: "1.0"
label: "v1.0"
path: /v1/
banner: "You're viewing docs for v1.0. <a href='/v2/'>Switch to latest</a>."
Options
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable versioning UI |
current |
string |
— | The version this build represents |
default |
string |
— | The default version (for future use) |
dropdown |
boolean |
true |
Show version dropdown in header |
list |
array |
[] |
All available versions |
Version Entry
Each item in list has:
| Key | Type | Required | Description |
|---|---|---|---|
version |
string |
Yes | Version identifier (e.g. "2.0") |
path |
string |
Yes | URL path where this version is deployed (/ for the site root) |
label |
string |
No | Display label in dropdown. Defaults to v{version} |
banner |
string |
No | Warning banner text (supports HTML). Shown when viewing this version |
source |
string or {tag/ref} |
No | Where this version's content comes from under --all-versions: a content directory, or a git ref checked out at build time. Defaults to content.dir |
sidebar |
array |
No | Sidebar for this version, replacing the shared one. Defaults to the shared sidebar narrowed to the pages this version has |
Building all versions at once
Keep each older version's content in a directory and point its source at it:
content:
dir: docs # live/latest content
versions:
enabled: true
current: "2.0"
list:
- version: "2.0"
label: "v2.0 (Latest)"
path: / # latest at the site root
- version: "1.0"
label: "v1.0"
path: /v1/
source: versions/1.0
banner: "You're viewing an older version. <a href='/'>Go to latest</a>."
stardust build --all-versions
# dist/ → v2.0 (indexed)
# dist/v1/ → v1.0 (noindex)
Keeping the current version at path: / serves it at the site root. If instead
every version lives under a prefix (e.g. current at /v2/), Stardust writes a
root index.html that redirects to the current version so the bare domain does
not 404.
Building an older version from a git tag
To avoid keeping old content in the tree, point source at a git tag or ref.
Stardust checks it out into a throwaway worktree, builds it, and cleans up — the
current checkout is never touched:
versions:
enabled: true
current: "2.0"
list:
- version: "2.0"
path: /
- version: "1.0"
path: /v1/
source:
tag: v1.0.0
The ref must be reachable in the local repository (git fetch --tags in CI first).
Version Dropdown
When dropdown: true, a version selector appears in the header next to the theme toggle. It shows the current version and lists all available versions as links.
Under --all-versions the switcher is page-preserving: from /v2/guide/ it
links each version to its /guide when that version has the page, and falls
back to the version's root otherwise. (A page that exists only as a draft in
another version also falls back to the root.)
To hide the dropdown while still using the banner:
versions:
enabled: true
current: "1.0"
dropdown: false
list:
- version: "1.0"
path: /
banner: "This version is outdated."
Version Banner
If the current version's entry has a banner field, an amber warning bar appears above the header. This is typically used on older versions to direct users to the latest.
The banner supports HTML, so you can include links:
banner: "You're viewing v1.0 docs. <a href='/v2/'>Switch to the latest version</a>."
The banner is dismissible — users can close it and their preference is saved in localStorage.
Workflow
Setting Up Versioning
Step 1: Decide on your version paths. A common convention:
| Version | Path | Notes |
|---|---|---|
| Latest (v2.0) | /v2/ or / |
Your main docs |
| Previous (v1.0) | /v1/ |
Older version |
Step 2: Add the versions config to each version's stardust.yaml. The list stays the same across all versions — only current changes.
For v2.0 (latest):
versions:
enabled: true
current: "2.0"
list:
- version: "2.0"
label: "v2.0 (Latest)"
path: /v2/
- version: "1.0"
label: "v1.0"
path: /v1/
banner: "You're viewing an older version. <a href='/v2/'>Go to latest</a>."
build:
outDir: build/v2
For v1.0 (previous):
versions:
enabled: true
current: "1.0"
list:
- version: "2.0"
label: "v2.0 (Latest)"
path: /v2/
- version: "1.0"
label: "v1.0"
path: /v1/
banner: "You're viewing an older version. <a href='/v2/'>Go to latest</a>."
build:
outDir: build/v1
Step 3: Build each version and merge the outputs:
# Build v2 (from main branch)
git checkout main
stardust build
# Build v1 (from v1 branch or tag)
git checkout v1.0
stardust build
# Merge into deploy directory
mkdir -p deploy
cp -r build/v2/* deploy/v2/
cp -r build/v1/* deploy/v1/
Using Git Branches
The most common approach is one branch per version:
main → v2.0 (latest)
v1.x → v1.0
Each branch has its own stardust.yaml with versions.current set appropriately. The versions.list is identical across branches.
Using Git Tags
Alternatively, use tags to snapshot versions:
git tag v1.0
# Continue developing on main for v2.0
Build from the tag when needed:
git checkout v1.0
stardust build
CI Example
GitHub Actions
name: Deploy Versioned Docs
on:
push:
branches: [main]
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # so git-ref-sourced versions can be checked out
- uses: nexlabstudio/stardust@v0.7.0
with:
args: --all-versions
- uses: actions/upload-pages-artifact@v3
with:
path: dist
- uses: actions/deploy-pages@v4
💡 Tip
--all-versions reads versions.list from your config and builds every version into dist/, each under its path (e.g. /v1/). Keep fetch-depth: 0 on checkout if any version's source is a git ref, so its tag can be checked out at build time.
Styling
The version UI components can be customized with CSS variables and class overrides.
CSS Variables
:root {
--version-banner-color: #b45309;
--version-banner-bg: color-mix(in srgb, #f59e0b 10%, var(--color-bg));
}
.dark {
--version-banner-color: #fbbf24;
}
Custom Styling
Override via custom CSS:
theme:
custom:
css: |
/* Red banner for deprecated versions */
:root {
--version-banner-color: #dc2626;
--version-banner-bg: color-mix(in srgb, #ef4444 10%, var(--color-bg));
}
/* Styled dropdown trigger */
.version-dropdown-trigger {
background: var(--color-primary);
color: white;
border-color: var(--color-primary);
}
See Theme Configuration — CSS Classes Reference for the full list of versioning classes.