vitepress-plugin-cross-site-router
Исправляет навигацию и prefetch между несколькими независимо развёрнутыми экземплярами VitePress на одном origin.
Проблема
При хостинге нескольких VitePress-сайтов на одном домене с разными base-путями (например /alt-server/, /alt-workstation/) возникают две проблемы:
- Ошибка SPA-навигации - VitePress перехватывает все клики по ссылкам одного origin и пытается выполнить SPA-переход, не находит чанки соседнего сайта и ломается.
- Лишние prefetch-запросы - prefetcher VitePress пытается предзагрузить страницы соседних сайтов, получая 404.
Решение
Плагин подменяет логику router'а и prefetch'а:
- Перехватывает
router.onBeforeRouteChange- если href не принадлежит текущему base, выполняетlocation.href(полный переход). - Оборачивает
window.IntersectionObserverдо того, как VitePress создаст prefetch-observer - ссылки на соседние сайты в очередь prefetch не попадают.
Установка
npm install @ampernic/vitepress-plugin-cross-site-routerИспользование
Плагин состоит из двух частей: Vite-плагин (опционален, зарезервирован для будущего) и клиентский рантайм.
VitePress config
import { CrossSiteRouterPlugin } from '@ampernic/vitepress-plugin-cross-site-router'
export default defineConfig({
vite: {
plugins: [CrossSiteRouterPlugin()],
},
})Theme enhanceApp
import {
installCrossSiteRouter,
suppressCrossSitePrefetch,
} from '@ampernic/vitepress-plugin-cross-site-router/client'
export default {
enhanceApp({ router, siteData }) {
installCrossSiteRouter(router, siteData)
suppressCrossSitePrefetch(siteData)
},
}API
installCrossSiteRouter(router, siteData, isCrossSite?)
Устанавливает хук router.onBeforeRouteChange, сохраняя ранее установленный хук в цепочке. Если целевой href не начинается с siteData.base или отсутствует в __VP_HASH_MAP__ (prod), выполняет location.href вместо SPA-перехода. Необязательный третий аргумент isCrossSite: (href, base) => boolean | undefined позволяет переопределить логику определения (возврат undefined роняет предикат в дефолт).
suppressCrossSitePrefetch(siteData, isCrossSite?)
Подменяет window.IntersectionObserver так, чтобы prefetch-observer VitePress никогда не добавлял в очередь ссылки, ведущие за пределы siteData.base. Третий аргумент такой же, как у installCrossSiteRouter - удобно передавать один и тот же предикат в обе функции.
isCrossSiteHref(href, base)
Утилита для проверки, является ли href межсайтовым относительно данного base. В prod-режиме учитывает __VP_HASH_MAP__ - страницы с общим префиксом base, но отсутствующие в текущей сборке, тоже считаются межсайтовыми (актуально для Forgejo Pages, где несколько распакованных инстансов делят родительский путь).
CrossSiteRouterPlugin(options?)
Vite-плагин. Сейчас пустой маркер ({ name: 'vitepress-plugin-cross-site-router' }) - вся логика живёт на клиенте. Точка входа для будущей build-time интеграции.
| Опция | Тип | Описание |
|---|---|---|
isCrossSite | (href, base) => boolean | undefined | Тип предиката определения межсайтовых ссылок. Сейчас плагином не применяется - передавайте его третьим аргументом в installCrossSiteRouter / suppressCrossSitePrefetch. |