This example shows how to manage versions throughout their complete lifecycle: from releasing a new version, marking it stable, deprecating older versions, and eventually archiving them.
A documentation version typically goes through these states:
| State | Badge | Description |
|---|---|---|
| Unreleased | info | Pre-release, beta, or release candidate |
| Current | primary | The latest released version |
| Stable | success | The recommended version for most users |
| Deprecated | warning | Still available but no longer maintained |
| Archived | (removed) | No longer available in documentation |
Let’s walk through a typical scenario where you have v1 and v2, and you’re releasing v3.
// astro.config.mjs - Before v3 release
export default defineConfig({
integrations: [
shipyardDocs({
versions: {
current: 'v2',
available: [
{ version: 'v2', label: 'Version 2.0' },
{ version: 'v1', label: 'Version 1.0', banner: 'unmaintained' },
],
deprecated: ['v1'],
stable: 'v2',
},
}),
],
})
First, add v3 as a pre-release version while still developing it:
// astro.config.mjs - v3 in development
export default defineConfig({
integrations: [
shipyardDocs({
versions: {
current: 'v2', // v2 is still the default
available: [
{ version: 'v3', label: 'Version 3.0 (Beta)', banner: 'unreleased' },
{ version: 'v2', label: 'Version 2.0' },
{ version: 'v1', label: 'Version 1.0', banner: 'unmaintained' },
],
deprecated: ['v1'],
stable: 'v2', // v2 is still stable
},
}),
],
})
Create the new version directory:
mkdir -p docs/v3
cp -r docs/v2/* docs/v3/
Update the content collection:
// src/content.config.ts
const docs = defineCollection(
createVersionedDocsCollection('./docs', {
versions: ['v1', 'v2', 'v3'], // Add v3
fallbackVersion: 'v2',
}),
)
When v3 is ready for release:
// astro.config.mjs - v3 released
export default defineConfig({
integrations: [
shipyardDocs({
versions: {
current: 'v3', // v3 is now current
available: [
{ version: 'v3', label: 'Version 3.0' }, // Remove 'unreleased' banner
{ version: 'v2', label: 'Version 2.0' },
{ version: 'v1', label: 'Version 1.0', banner: 'unmaintained' },
],
deprecated: ['v1'],
stable: 'v3', // v3 is now stable
},
}),
],
})
What changes:
/docs/ are redirected to /docs/v3//docs/latest/ now points to v3After v3 has been stable for some time, deprecate v2:
// astro.config.mjs - v2 deprecated
export default defineConfig({
integrations: [
shipyardDocs({
versions: {
current: 'v3',
available: [
{ version: 'v3', label: 'Version 3.0' },
{ version: 'v2', label: 'Version 2.0', banner: 'unmaintained' }, // Add banner
{ version: 'v1', label: 'Version 1.0', banner: 'unmaintained' },
],
deprecated: ['v1', 'v2'], // Add v2 to deprecated list
stable: 'v3',
},
}),
],
})
What changes:
When a version is so old that it’s no longer useful, remove it entirely:
// astro.config.mjs - v1 archived
export default defineConfig({
integrations: [
shipyardDocs({
versions: {
current: 'v3',
available: [
{ version: 'v3', label: 'Version 3.0' },
{ version: 'v2', label: 'Version 2.0', banner: 'unmaintained' },
// v1 removed from available
],
deprecated: ['v2'], // Remove v1 from deprecated
stable: 'v3',
},
}),
],
})
Update the content collection:
// src/content.config.ts
const docs = defineCollection(
createVersionedDocsCollection('./docs', {
versions: ['v2', 'v3'], // Remove v1
fallbackVersion: 'v3',
}),
)
Optionally archive the content:
# Archive v1 content (optional, for reference)
tar -czf archive/docs-v1.tar.gz docs/v1/
rm -rf docs/v1/
Here’s how the configuration evolves over a typical version lifecycle:
Time ──────────────────────────────────────────────────────────────────>
v1: [stable]────────[deprecated]──────────────────────[archived]
v2: [unreleased]──[stable]───────[deprecated]───────────────>
v3: [unreleased]──[stable]───────────────>
v4: [unreleased]──────>
Point A: v2 is new
versions: {
current: 'v1',
available: [
{ version: 'v2', label: 'Version 2.0 (Beta)', banner: 'unreleased' },
{ version: 'v1', label: 'Version 1.0' },
],
deprecated: [],
stable: 'v1',
}
Point B: v2 released
versions: {
current: 'v2',
available: [
{ version: 'v2', label: 'Version 2.0' },
{ version: 'v1', label: 'Version 1.0' },
],
deprecated: [],
stable: 'v2',
}
Point C: v1 deprecated
versions: {
current: 'v2',
available: [
{ version: 'v2', label: 'Version 2.0' },
{ version: 'v1', label: 'Version 1.0', banner: 'unmaintained' },
],
deprecated: ['v1'],
stable: 'v2',
}
Point D: v3 released, v1 archived
versions: {
current: 'v3',
available: [
{ version: 'v3', label: 'Version 3.0' },
{ version: 'v2', label: 'Version 2.0', banner: 'unmaintained' },
],
deprecated: ['v2'],
stable: 'v3',
}
Deprecate a version when:
Archive a version when:
A typical deprecation timeline:
banner property to show clear warnings on deprecated versionslabel to include status (e.g., “Version 1.0 (Legacy)”)For pre-release versions:
{ version: 'v3-rc', label: 'Version 3.0 RC1', path: 'v3-rc', banner: 'unreleased' }
For LTS versions that receive extended support:
{
current: 'v4',
available: [
{ version: 'v4', label: 'Version 4.0' },
{ version: 'v3-lts', label: 'Version 3.0 LTS', path: 'v3-lts' },
{ version: 'v2', label: 'Version 2.0', banner: 'unmaintained' },
],
deprecated: ['v2'],
stable: 'v4', // or 'v3-lts' if LTS is recommended for production
}
When maintaining two active major versions (e.g., Python 2/3 situation):
{
current: 'v3',
available: [
{ version: 'v3', label: 'Version 3.x' },
{ version: 'v2', label: 'Version 2.x' }, // No deprecation banner
],
deprecated: [],
stable: 'v3', // Recommend v3 for new projects
}