Skip to content

vitepress-plugin-single-page

Build-time Vite-плагин: для каждой версии документации генерирует single.md — все главы версии, склеенные в одну предрендеренную страницу. Зачем:

  • Ctrl+F по всему документу — мгновенно, без N клиентских запросов.
  • Pagefind (или другой статический поиск) индексирует версию как единый документ.
  • Открытие — обычная статическая HTML-страница: ни iframe, ни JS-водопада.

Установка

bash
npm install -D @ampernic/vitepress-plugin-single-page

Использование

ts
// .vitepress/config.ts
import { defineConfig } from 'vitepress'
import { SinglePagePlugin } from '@ampernic/vitepress-plugin-single-page'

export default defineConfig({
  vite: {
    plugins: [
      SinglePagePlugin({ distroName: 'alt-server' }),
    ],
  },
})

Каждая директория версии под docs/<locale>/ получает single.md, который VitePress собирает в маршрут /<version>/single.

Опции

ОпцияТипПо умолчаниюОписание
srcDirstring'docs'Исходная директория VitePress
localestring'ru'Папка локали внутри srcDir
distroNamestringSlug; нужен для поиска .vitepress/sidebars/<distro>/<v>.ts
versionPatternRegExp/^(\d+\.\d+(\.\d+)*|p\d+)$/Какие директории считать версиями
pageNamestring'single'Имя генерируемого файла
titleTemplatestring'{distro} {version} — на одной странице'Шаблон заголовка
frontmatterobjectFrontmatter, добавляемый к каждой странице
sidebarOrder(srcDir, version, options) => string[]встроенныйСвоя функция порядка глав

Как работает

  1. На configResolved (до того как VitePress сканирует дерево) плагин обходит директории версий.
  2. Для каждой версии читает порядок глав из .vitepress/sidebars/.../<v>.ts (или из sidebarOrder).
  3. Склеивает index.md версии и всех глав, переписывая относительные пути ассетов так, чтобы они резолвились от single.md (Vite дедуплицирует ассеты по контент-хэшу).
  4. Пишет single.md в дерево до сканера VitePress — страница появляется как обычный маршрут.

Каждой главе присваивается стабильный якорь sp-<slug> (см. singleAnchorId), на который ссылается клиентский ребайнд сайдбара в теме.

Известные ограничения / edge cases

  • Юникод в путях: слаги глав нормализуются через [^\p{L}\p{N}_-]+ (не через \w, который в JS охватывает только латиницу). Без этого кириллический путь install-packages-advanced/введение/ схлопнулся бы в тот же префикс, что и родительская страница install-packages-advanced/, и якоря {#part-id} дублировались бы между страницами.
  • Дедупликация анкоров: явные {#id} и внутристраничные ссылки ](#id) префиксуются slug'ом главы, чтобы VitePress не падал на «duplicate user-defined id».
  • dropInitialTOC: срезает висячий ## Содержание (заголовок и всё, что до конца документа), если книга-рут уже содержит текстовый TOC. Опция независима от injectTOC, который вставляет <ADBookTOC> в начало склейки.