Skip to content

vitepress-alt-docs-versioning

Documentation versioning plugin for VitePress. Scans the file structure at build time, injects version/edition data through define and ships a component and composable that expose the current version.

Installation

bash
npm install @ampernic/vitepress-plugin-alt-docs-versioning

Concept

Documentation is organized as docs/ru/{version}/.... The plugin:

  1. Scans the docs/ru/ directory and finds every version (directories such as 11.0, 11.1, 11.1-edu and so on)
  2. Compiles the data into a VersionInfo object and injects it via Vite define as __VERSIONS_DATA__
  3. The client-side composable useVersionsData() reads that data

Both single distro mode (one site = one distribution) and multi distro mode (one site = several distributions) are supported.

Usage

Vite plugin

ts
import { VersioningPlugin } from '@ampernic/vitepress-plugin-alt-docs-versioning'

export default defineConfig({
  vite: {
    plugins: [
      VersioningPlugin({
        distroName: 'alt-server',   // slug of the current distribution
        allDistros: ['alt-server', 'alt-workstation', 'alt-education'],
      }),
    ],
  },
})
OptionTypeDescription
distroNamestringSlug of the current distribution. The plugin only scans its versions
allDistrosstring[]Full list of distributions for the switcher (the rest appear as stubs without versions). When a distros.json sits next to the config, that file wins over this option
sectionsSectionInfo[]Groups distributions into named sections (see below). When a sections.json sits next to the config, it is used if sections is empty
debugbooleanSingle-line build report: mode (per-distro, multi-scan, ...), number of distributions, current-distro versions, section count. When using the theme, toggled via createSharedConfig({ debug: true })

Sections (sections)

Group several distributions under a shared submenu in the product switcher (ADProducts):

ts
VersioningPlugin({
  distroName: 'alt-domain',
  allDistros: ['alt-domain', 'alt-workstation', 'alt-virtualization-pve', 'alt-virtualisation-one', 'group-policy'],
  sections: [
    { name: 'ALT Virtualization', distros: ['alt-virtualization-pve', 'alt-virtualisation-one'] },
    { name: 'Group Policies', distros: ['group-policy'] },
  ],
})

A section takes one of two shapes:

  • Group: { name, distros: [<slug>, ...] } renders a submenu with several distributions
  • Flat entry: { name, distro: <slug> } renders a single labeled entry with no nested submenu

Menu ordering rules:

  • Distributions inside sections render in declaration order
  • Distributions without a section and without the -e2k suffix render as a flat list at the top
  • Distributions without a section that carry the -e2k suffix land in the auto-group "For Elbrus" at the bottom

Automatic sections.json and distros.json loading:

When sections is not passed explicitly, the plugin looks for sections.json at the project root (process.cwd()). allDistros is picked up from distros.json in the same directory when present. Both files are written from outside (per-branch deploy), so no manual config edits are needed.

json
[
  { "name": "ALT Virtualization", "distros": ["alt-virtualization-pve", "alt-virtualisation-one"] },
  { "name": "Group Policies", "distros": ["group-policy"] }
]

distros.json is just an array of slugs:

json
["alt-server", "alt-workstation", "alt-education"]

ADVersioning component

A ready-made version switcher:

vue
<script setup>
import { ADVersioning } from '@ampernic/vitepress-plugin-alt-docs-versioning/client'
</script>

<template>
  <ADVersioning />
</template>

Register it via app.component() in enhanceApp or use it directly in .vitepress/theme.

useVersionsData() composable

ts
import { useVersionsData } from '@ampernic/vitepress-plugin-alt-docs-versioning/client'

const data = useVersionsData()
// data.distros['alt-server'].versions -> ['11.0', '11.1']
// data.distros['alt-server'].latest   -> '11.1'

Types

ts
interface DistroEdition {
  name: string   // display name of the edition
  path: string   // path relative to the version
}

interface DistroInfo {
  versions: string[]
  latest: string
  title?: string
  editions?: { [version: string]: DistroEdition[] }
}

// Group (`distros`) and flat entry (`distro`) are mutually exclusive.
type SectionInfo =
  | { name: string; distros: string[]; distro?: never }
  | { name: string; distro: string; distros?: never }

interface VersionsData {
  distros: { [distroName: string]: DistroInfo }
  sections?: SectionInfo[]
}

File layout

The plugin expects the following structure:

docs/
  ru/
    11.0/
      index.md
      ...
    11.1/
      index.md
      ...
    11.1-edu/          # edition via suffix
      index.md
      ...