Расширение темы по умолчанию
Тема VitePress по умолчанию оптимизирована для документации и может быть настроена по вашему усмотрению. Полный список опций можно найти в главе Настройки темы по умолчанию.
Однако есть ряд случаев, когда одной лишь конфигурации будет недостаточно. Например:
- Вам нужно изменить стили CSS;
- Вам нужно изменить экземпляр приложения Vue, например, чтобы зарегистрировать глобальные компоненты;
- Вам нужно внедрить пользовательский контент в тему через слоты макета.
Эти расширенные настройки потребуют использования пользовательской темы, которая «расширяет» тему по умолчанию.
СОВЕТ
Прежде чем приступить к работе, обязательно прочитайте главу Пользовательская тема, чтобы понять, как работают пользовательские темы.
Настройка CSS
CSS темы по умолчанию можно настроить, переопределив переменные CSS корневого уровня:
import DefaultTheme from 'vitepress/theme'
import './custom.css'
export default DefaultTheme/* .vitepress/theme/custom.css */
:root {
--vp-c-brand-1: #646cff;
--vp-c-brand-2: #747bff;
}См. переменные CSS темы по умолчанию, которые можно переопределить.
Навбар
Навбар отрисовывает единую поверхность фона, управляемую CSS-переменными, поэтому его вид можно изменить, не затрагивая внутреннюю реализацию компонента:
:root {
/* высота бара и фон */
--vp-nav-height: 4rem;
--vp-nav-bg-color: var(--vp-c-bg);
/* фон, когда находимся поверх главной страницы (без прокрутки);
установите var(--vp-nav-bg-color), чтобы отказаться от прозрачного оформления */
--vp-nav-home-bg-color: transparent;
/* фильтр, применяемый к контенту за баром */
--vp-nav-backdrop-filter: none;
/* нижняя линия бара и фон мобильного меню */
--vp-nav-divider-color: var(--vp-c-gutter);
--vp-nav-screen-bg-color: var(--vp-c-bg);
}Например, навбар в стиле матового стекла:
:root {
--vp-nav-bg-color: color-mix(in srgb, var(--vp-c-bg) 65%, transparent);
--vp-nav-backdrop-filter: saturate(180%) blur(8px);
}Та же обработка распространяется и на локальную навигацию: --vp-local-nav-bg-color по умолчанию следует за цветом поверхности навбара, и там, где два бара соприкасаются, они разделяют единую размытую поверхность, так что стекло остаётся непрерывным между ними.
ПРЕДУПРЕЖДЕНИЕ
backdrop-filter заметно влияет на производительность прокрутки, особенно на больших или High-DPI экранах. При использовании полупрозрачного бара также проверьте контрастность текста поверх содержимого страницы. Safari 17 и более ранние версии не применяют управляемые переменными backdrop-фильтры, поэтому показывают полупрозрачный цвет без размытия.
Когда элементы навигации не помещаются в доступную ширину, они перемещаются в меню ⋯ в конце навбара вместо того, чтобы обрезаться, начиная с ссылок на соцсети, переключателя внешнего вида и переключателя локали, за которыми следуют элементы навигации справа налево. Подпись этой кнопки можно локализовать с помощью extraMenuLabel.
Использование различных шрифтов
VitePress использует Inter в качестве шрифта по умолчанию, и будет включать шрифты в вывод сборки. Шрифт также автоматически загружается в производство. Однако это может быть нежелательно, если вы хотите использовать другой основной шрифт.
Чтобы не включать Inter в вывод сборки, импортируйте тему из vitepress/theme-without-fonts:
import DefaultTheme from 'vitepress/theme-without-fonts'
import './my-fonts.css'
export default DefaultTheme/* .vitepress/theme/my-fonts.css */
:root {
--vp-font-family-base: /* normal text font */ --vp-font-family-mono:
/* code font */;
}ПРЕДУПРЕЖДЕНИЕ
Если вы используете дополнительные компоненты, такие как Страница команды, убедитесь, что они также импортированы из vitepress/theme-without-fonts!
Если ваш шрифт — это локальный файл, на который ссылаются через @font-face, он будет обработан как ресурс и включён в каталог .vitepress/dist/assets с хэшированным именем файла. Чтобы предварительно загрузить этот файл, используйте хук сборки transformHead:
export default {
transformHead({ assets }) {
// настраиваем regex соответствующим образом, чтобы он соответствовал вашему шрифту
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
if (myFontFile) {
return [
[
'link',
{
rel: 'preload',
href: myFontFile,
as: 'font',
type: 'font/woff2',
crossorigin: ''
}
]
]
}
}
}Регистрация глобальных компонентов
import DefaultTheme from 'vitepress/theme'
/** @type {import('vitepress').Theme} */
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
// регистрируем пользовательские глобальные компоненты
app.component('MyGlobalComponent' /* ... */)
}
}Если вы используете TypeScript:
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
// регистрируем пользовательские глобальные компоненты
app.component('MyGlobalComponent' /* ... */)
}
} satisfies ThemeПоскольку мы используем Vite, можно применять глобальную функцию импорта Vite для автоматической регистрации каталога компонентов.
Слоты макета
Компонент <Layout/> темы по умолчанию имеет несколько слотов, которые можно использовать для вставки содержимого в определённые места страницы. Вот пример внедрения компонента перед оглавлением:
import DefaultTheme from 'vitepress/theme'
import MyLayout from './MyLayout.vue'
export default {
extends: DefaultTheme,
// переопределяем макет с помощью компонента-обёртки,
// который внедряет слоты
Layout: MyLayout
}<script setup>
import DefaultTheme from 'vitepress/theme'
const { Layout } = DefaultTheme
</script>
<template>
<Layout>
<template #aside-outline-before>
Мой пользовательский контент в верхней части боковой панели
</template>
</Layout>
</template>Также можно использовать функцию рендеринга.
import { h } from 'vue'
import DefaultTheme from 'vitepress/theme'
import MyComponent from './MyComponent.vue'
export default {
extends: DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'aside-outline-before': () => h(MyComponent)
})
}
}Полный список слотов, доступных в макете темы по умолчанию:
- Когда
layout: 'doc'(по умолчанию) включен через метаданные:doc-topdoc-bottomdoc-footer-beforedoc-beforedoc-aftersidebar-nav-beforesidebar-nav-afteraside-topaside-bottomaside-outline-beforeaside-outline-afteraside-ads-beforeaside-ads-after
- Когда
layout: 'home'включен через метаданные:home-hero-beforehome-hero-info-beforehome-hero-infohome-hero-info-afterhome-hero-actions-before-actionshome-hero-actions-afterhome-hero-imagehome-hero-afterhome-features-beforehome-features-after
- Когда
layout: 'page'включен через метаданные:page-toppage-bottom
- На странице «Не найдено (404)»:
not-found
- Всегда:
layout-toplayout-bottomnav-bar-title-beforenav-bar-title-afternav-bar-content-beforenav-bar-content-afternav-screen-content-beforenav-screen-content-after
Использование View Transitions API
Переключение внешнего вида
Вы можете расширить стандартную тему, чтобы обеспечить пользовательский переход при переключении цветового режима. Пример:
<script setup lang="ts">
import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { nextTick, provide } from 'vue'
const { isDark } = useData()
const enableTransitions = () =>
'startViewTransition' in document &&
window.matchMedia('(prefers-reduced-motion: no-preference)').matches
provide('toggle-appearance', ({ clientX, clientY }: MouseEvent) => {
if (!enableTransitions()) {
isDark.value = !isDark.value
return
}
const x = (100 * clientX) / innerWidth
const y = (100 * clientY) / innerHeight
const maxRadius =
(100 *
Math.hypot(
Math.max(clientX, innerWidth - clientX),
Math.max(clientY, innerHeight - clientY)
)) /
(Math.hypot(innerWidth, innerHeight) / Math.SQRT2)
document.documentElement.style.setProperty('--switch-x', `${x}%`)
document.documentElement.style.setProperty('--switch-y', `${y}%`)
document.documentElement.style.setProperty('--switch-r', `${maxRadius}%`)
document.startViewTransition(async () => {
isDark.value = !isDark.value
await nextTick()
})
})
</script>
<template>
<DefaultTheme.Layout />
</template>
<style>
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-new(root) {
animation: switch-appearance 300ms ease-in;
}
.dark::view-transition-new(root) {
animation: none;
}
.dark::view-transition-old(root) {
animation: switch-appearance 300ms ease-in reverse forwards;
z-index: 1;
}
@keyframes switch-appearance {
from {
clip-path: circle(0 at var(--switch-x) var(--switch-y));
}
to {
clip-path: circle(var(--switch-r) at var(--switch-x) var(--switch-y));
}
}
.VPSwitchAppearance {
width: 1.375rem !important;
}
.VPSwitchAppearance .check {
transform: none !important;
}
</style>Результат (предупреждение!: мигающие цвета, резкие движения, яркий свет):
Демонстрация

Более подробно о переходах между представлениями читайте в документации Chrome.
Изменение маршрута
Скоро будет.
Переопределение внутренних компонентов
Вы можете использовать псевдонимы Vite, чтобы заменить стандартные компоненты темы на свои собственные:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vitepress'
export default defineConfig({
vite: {
resolve: {
alias: [
{
find: /^.*\/VPNavBar\.vue$/,
replacement: fileURLToPath(
new URL('./components/CustomNavBar.vue', import.meta.url)
)
}
]
}
}
})Чтобы узнать точное название компонента, обратитесь к нашему исходному коду. Поскольку компоненты являются внутренними, есть небольшая вероятность того, что их название будет обновлено между минорными выпусками.