Skip to content

vitepress-theme-alt-docs

Shared VitePress theme for ALT Linux documentation. Combines every package of the monorepo into a ready-to-use configuration.

Installation

bash
npm install @ampernic/vitepress-theme-alt-docs

The theme pulls the other packages in as dependencies automatically.

Wiring

Theme (theme/index.ts)

ts
export { Theme as default } from '@ampernic/vitepress-theme-alt-docs'

Config (.vitepress/config/index.mts)

ts
import { createSharedConfig } from '@ampernic/vitepress-theme-alt-docs/config'

const shared = createSharedConfig({
  distroName: 'alt-server',
  allDistros: ['alt-server', 'alt-workstation', 'alt-education'],
  hostname: 'https://docs.altlinux.org',
})

export default defineConfigWithTheme({
  ...shared,
  rewrites: { 'ru/:slug*': ':slug*' },
  locales: {
    root: { label: 'Russian', ...ru },
  },
})

createSharedConfig(options)

OptionTypeDefaultDescription
distroNamestring-Distribution slug (e.g. 'alt-server'). Required
productNamestring-Display name of the product. Wired into the PWA manifest, <title>, LLM output
allDistrosstring[]-List of every distribution shown in the switcher. distros.json next to the config wins over the option
sectionsSectionInfo[]-Distribution groupings in the switcher; sections.json next to the config wins
productLinksRecord<string, string>-Slug -> external product page. The current distribution link is fed to export.logoLink automatically
hostnamestring-Absolute hostname used for sitemap, canonical, og:image
editLinkRepostringalt-docs/docs-vitepressForgejo repository for the "Suggest an edit" button
exportExportPluginOptions-Options for PDF / HTML / EPUB export. When absent, no export runs
metaMetaPluginOptions | falsedefaultsSEO / OG / canonical. false disables MetaPlugin entirely
llmsLlmsPluginOptions | falsedefaultsllms.txt / llms-full.txt / per-page mirror. false disables
singlePageOmit<SinglePagePluginOptions, 'distroName'>-Single-page options (e.g. dropInitialTOC: true)
reportIssuefalse | { repo?; origin?; labels?; shortcut? }alt-docs/docs-vitepressCtrl+Enter -> Forgejo new issue. false disables
optimizeImagesboolean | OptimizeImagesOptionsonLosslessly recompresses PNGs in the built site before the export bundles inline them. false skips it
debugbooleanfalseSingle flag that enables debug in every nested plugin (a nested debug option still wins over it)

Bundled plugins

PluginWhat it gives you
vitepress-plugin-pagefindPagefind search filtered by version
vitepress-alt-docs-versioningVersion and edition switcher
vitepress-plugin-breadcrumbsBreadcrumbs above the content
vitepress-plugin-cross-site-routerCross-site navigation
vitepress-plugin-single-pageSingle-page view of a version
vitepress-plugin-exportVersion export to PDF / HTML / EPUB
vitepress-plugin-html-imageNormalizes <img> in raw HTML
vitepress-plugin-metaCanonical, sitemap, Open Graph, OG image
vitepress-plugin-llmsllms.txt, llms-full.txt, per-page markdown mirror
vitepress-plugin-report-issueCtrl+Enter -> pre-filled Forgejo issue
alt-docs-registryShared distribution registry (products.yaml)
@nolebase/vitepress-plugin-enhanced-readabilitiesContent width switcher
vitepress-plugin-tabsTabs in Markdown
markdown-it-kbd<kbd> syntax
markdown-it-attrs{#id .class} after headings
@alt-gnome/markdown-it-custom-containersContainers left, center, right

Layout slots

The theme occupies the following VitePress slots:

SlotComponent
layout-topReportIssueDialog ("Report a problem" modal)
nav-bar-content-beforeSearch bar (button + modal)
nav-bar-content-afterNolebase menu (readability settings)
nav-screen-content-afterMobile menu: ExportButton + Nolebase
sidebar-nav-beforeDistribution switcher
doc-beforeBreadcrumbs
doc-footer-beforeReportIssueLink (link that opens the modal)
aside-outline-beforeExportButton (format switcher)
aside-outline-afterADFootnotesOutline (footnotes next to the outline)
home-hero-beforeLanding (product cards) on layout: home

Landing and index pages

Landing (layout: home)

The landing (index site) uses layout: home; the content is rendered by theme components driven by frontmatter altHome:

yaml
---
layout: home
altHome:
  hero:
    logo: basealt
    title: BaseALT Documentation
    text: Official documentation of the ALT operating system.
  products:
    alt-server:
      tagline: Complete server solution for IT infrastructure
      accent: '#8e96a3'
      grad: ['#c8d0dd', '#8e96a3']
  footer:
    links:
      - { title: Company site, url: https://www.basealt.ru/ }
    copyright: (c) 2026 BaseALT
---

The list of distributions and sections comes from __VERSIONS_DATA__ (the versioning plugin); altHome.products[<slug>] sets the tagline and accent color of the card (the default name comes from the shared registry).

Distribution landing

The distribution landing template renders <VersionList distro="<slug>" />, releases grouped by major version, cards with lists and an "Actual" badge.

Content layout

The theme expects files at docs/ru/{version}/... with the rewrite rule ru/:slug* -> :slug*.

docs/
  ru/
    11.0/
      index.md
    11.1/
      index.md
  public/
    favicon.ico
    branding/

Search only works in the production build. pagefind must be installed as a devDependency of the docs project for indexing:

bash
npm install -D pagefind

After vitepress build, pagefind --site .vitepress/dist runs automatically. Search is filtered by the current page version.

Image recompression

Screenshots arrive from the authoring pipeline at whatever compression the capture tool chose, which is usually none. Re-encoding at full effort returns about two thirds of their bytes, pixel for pixel.

That matters twice over: readers download these, and the export bundles inline them as base64, where they make up the bulk of the document handed to the PDF renderer.

Measured on one distribution:

beforeafter
images in the build51.1 MB16.2 MB
page load in chromium4.6 s2.3 s
building one PDF22.3 s17.2 s
PDF size48.2 MB39.6 MB

The pass itself took 12.8 s over 632 files.

Lossless on purpose: these are UI screenshots full of small text, where the ringing a lossy codec leaves around glyphs is exactly what a reader zooms in to escape.

Requires sharp; without it the step is skipped with a warning rather than failing the build. Tunables are exclude, minBytes and concurrency.