Skip to content

vitepress-plugin-pagefind

Интеграция Pagefind в VitePress — статический поиск с фильтрацией, нулевой нагрузкой на бандл и готовым UI-компонентом.

Что даёт по сравнению со встроенным локальным поиском VitePress:

  • Нет 2 МБ MiniSearch-индекса в бандле — Pagefind грузит чанки лениво (~45 КБ при первом поиске)
  • Настраиваемые фильтры (по дистрибутиву, версии и т.д.)
  • Поддержка объединения индексов нескольких сайтов (mergeIndex) для глобального поиска
  • Подсветка совпадений в сниппетах из коробки

Установка

bash
npm install -D @ampernic/vitepress-plugin-pagefind pagefind

pagefind — CLI-инструмент для индексации, нужен как devDependency в проекте документации.

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

1. Подключение в VitePress config

ts
// .vitepress/config.ts
import { defineConfig } from 'vitepress'
import { PagefindPlugin } from '@ampernic/vitepress-plugin-pagefind'

export default defineConfig({
  ...PagefindPlugin({
    distroName: 'alt-workstation',  // slug сайта для фильтра distro
    extractFilters: (id) => {
      // Тегируем страницы по версии (извлекаем из пути файла)
      const m = id.match(/[/\\](\d+\.\d+(?:-\w+)?)[/\\]/)
      return m ? { version: m[1] } : null
    },
  }),
  // ... остальной конфиг
})

Плагин добавляет в конфиг:

  • transformHtml — инжектит <span hidden data-pagefind-filter="..."> перед </body> на каждой странице
  • buildEnd — записывает pagefind/distro-meta.json, затем запускает pagefind --site .vitepress/dist

2. Компонент поиска

vue
<script setup lang="ts">
import { PagefindSearch } from '@ampernic/vitepress-plugin-pagefind/client'
import { useRoute } from 'vitepress'
import { computed } from 'vue'

const route = useRoute()

const filters = computed(() => {
  const m = route.path.match(/^\/(\d+\.\d+(?:-\w+)?)\//)
  const ver = m?.[1]
  return ver ? { version: ver } : {}
})
</script>

<template>
  <PagefindSearch
    :filters="filters"
    :placeholder="filters.version ? `Поиск в версии ${filters.version}…` : 'Поиск…'"
    @close="/* закрыть */"
  />
</template>

API

PagefindPlugin(options?)

Возвращает фрагмент VitePress-конфига. Spread'ится в корень конфига:

ts
export default defineConfig({
  ...PagefindPlugin({ ... }),
  vite: {
    plugins: [...PagefindPlugin({ ... }).vite.plugins, /* другие плагины */],
  },
})
ОпцияТипПо умолчаниюОписание
outDirstring'.vitepress/dist'Директория собранного сайта для индексации
distroNamestringSlug дистрибутива — инжектируется как фильтр distro:<distroName> на каждой странице
extractFilters(filePath: string) => Record<string, string> | nullФункция извлечения дополнительных фильтров из пути выходного HTML-файла
extraArgsstring[][]Дополнительные аргументы CLI pagefind

PagefindSearch (компонент)

PropТипПо умолчаниюОписание
filtersRecord<string, string>{}Фильтры для поиска (e.g. { version: '11.1' })
placeholderstring'Search…'Placeholder текстового поля
maxResultsnumber12Максимальное количество результатов

Emit: close — при закрытии модального окна.

Как работает фильтрация

  1. Во время сборки transformHtml добавляет по одному скрытому <span> на фильтр перед </body>:

    html
    <span hidden data-pagefind-filter="distro:alt-workstation"></span>
    <span hidden data-pagefind-filter="version:11.1"></span>

    Важно: нельзя использовать несколько атрибутов data-pagefind-filter на одном элементе — HTML-спецификация оставляет только первый дубликат. Для нескольких фильтров нужны отдельные элементы.

  2. Собранные значения фильтров сохраняются в pagefind/distro-meta.json при buildEnd:

    json
    {"distro":["alt-workstation"],"version":["10.0","10.1","11.0","11.1","11.2"]}

    Этот файл используется компонентом ADGlobalSearch для точного отображения версий по каждому дистрибутиву — pagefind.filters() при объединённых индексах возвращает значения со всех сайтов без изоляции.

  3. Pagefind индексирует атрибуты при buildEnd.

  4. В рантайме фильтры передаются в pagefind.search(query, { filters: { version: '11.1' } }).

Поведение в dev-режиме

Плагин подключает Vite-middleware, который отдаёт файлы из outDir/pagefind/ — поиск работает по индексу от последней vitepress build.

bash
vitepress build  # собрать индекс один раз
vitepress dev    # поиск работает