vitepress-plugin-llms
Публикует LLM-совместимые артефакты для сайта VitePress: индекс llmstxt.org (/llms.txt), полнотекстовый дамп всех страниц одним файлом (/llms-full.txt) и зеркало каждой страницы в исходном Markdown (<url>.md). Инструмент, который скачивает /foo/index.md, получает исходник, а не HTML-обёртку VitePress.
Полезно, когда документацию хотят видеть роботы поисковой выдачи (GEO), ассистенты вроде ChatGPT/Claude и внутренние RAG-пайплайны -- HTML-рендер VitePress для них избыточен и шумит вёрсткой.
Установка
pnpm add @ampernic/vitepress-plugin-llmsЕсли пакет ставится из Forgejo, а не из npmjs, дополнительно пропишите скоуп в .npmrc:
@ampernic:registry=https://altlinux.space/api/packages/ampernic/npm/Использование
Плагин возвращает три хука VitePress-конфига -- их надо разложить в корень defineConfig:
// .vitepress/config.ts
import { defineConfig } from 'vitepress'
import { LlmsPlugin } from '@ampernic/vitepress-plugin-llms'
const llms = LlmsPlugin({
hostname: 'https://docs.altlinux.space',
title: 'ALT Linux Documentation',
description: 'Справочная документация по дистрибутивам ALT.',
section: (p) => p.url.split('/').filter(Boolean)[0] ?? 'root',
filter: (p) => !p.url.endsWith('/404.html'),
})
export default defineConfig({
transformPageData: llms.transformPageData,
buildEnd: llms.buildEnd,
vite: llms.vite,
})Через createSharedConfig темы @ampernic/vitepress-theme-alt-docs эти хуки пробрасываются автоматически -- опции передаются полем llms.
В dev-режиме vite.plugins добавляет middleware, отдающий .md с Content-Type: text/markdown; charset=utf-8, чтобы браузер и внешние клиенты не ошибались на MIME.
Опции
| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
hostname | string | -- | Абсолютный origin для полей absoluteUrl в llms.txt / llms-full.txt. Без него URL остаются root-relative |
title | string | 'Documentation' | Заголовок llms.txt и llms-full.txt. По умолчанию берётся из frontmatter корневой страницы (altHome.hero.title или title) |
description | string | '' | Однострочное описание сразу под заголовком. Фолбэк тоже из корневого frontmatter |
fallbackSummary | string | '' | Подпись пункта в llms.txt, если у страницы нет первого абзаца |
emitIndex | boolean | true | Писать llms.txt |
emitFullText | boolean | true | Писать llms-full.txt |
emitPerPageMarkdown | boolean | true | Для каждой страницы класть зеркало <url>.md рядом с HTML |
filter | (page: PageMeta) => boolean | -- | Отсекает страницы (автогенерированные индексы, редиректы) от всех артефактов |
section | (page: PageMeta) => string | первый сегмент URL | Ключ группировки в дереве llms.txt |
pageTitle | (page: PageMeta) => string | frontmatter title | pageData.title | Пере-именовывает пункт в индексе |
summary | (page: PageMeta) => string | первый абзац источника | Однострочник страницы в llms.txt |
renderSource | (page: PageMeta) => string | undefined | -- | Переписывает то, что попадает в артефакты и per-page .md. Нужно, чтобы разложить frontmatter-driven лэндинги (<DocSections />) в реальный Markdown для LLM |
fullTextMaxBytes | number | 8 * 1024 * 1024 | Жёсткий предел размера llms-full.txt. Старые LLM-клиенты давятся многомегабайтными файлами. 0 -- без ограничения |
preamble | string | -- | Дополнительный Markdown-блок в шапке llms.txt -- контакты, лицензия, описание проекта |
extraPages | () => SyntheticPage[] | -- | Синтетические страницы, дописываемые в набор перед emit. Пригодится сайту-агрегатору, который сам страницы не хостит, но перечисляет их |
Что попадает в артефакты
llms.txt: заголовок + описание + опциональный preamble + плоский список бессекционных элементов + сгруппированные поsection(page)пункты со ссылками и однострочником каждой страницы.llms-full.txt: заголовок + описание + один блок на страницу, разделитель---, шапкаurl:/title:. Порядок -- лексикографический по URL, чтобы разница между сборками была детерминированной.- Per-page
.md: сырой Markdown из репозитория. При<url>/VitePress отдаёт<url>index.md, при<url>--<url>.md.
Нюансы вывода
renderSourceвызывается доfilter. Если корневой лэндинг рендерится из frontmatter, вернуть из него полноценный Markdown -- единственный способ показать его LLM осмысленно.- Заголовок и описание
llms.txtрезолвятся так: параметры плагина >altHome.hero.title/altHome.hero.textкорневой страницы > еёtitle/description> дефолты. На перстрановом сайте "корень" -- это${base}(например,/alt-workstation/), а не/. - При
hostnameне задан URL пунктов -- root-relative. Индексаторы GEO часто требуют абсолютные ссылки, лучше задавать всегда. - Per-page
.mdпишется вoutDirбез префиксаsite.base: при деплое дистрибутив уже лежит под/<distro>/, повторный префикс дал бы404.