4.0 KiB
Theming
Using a Custom Theme
You can enable a custom theme by adding the .vitepress/theme/index.js
file (the "theme entry file").
.
├─ docs
│ ├─ .vitepress
│ │ ├─ theme
│ │ │ └─ index.js
│ │ └─ config.js
│ └─ index.md
└─ package.json
A VitePress custom theme is simply an object containing three properties and is defined as follows:
interface Theme {
Layout: Component // Vue 3 component
NotFound?: Component
enhanceApp?: (ctx: EnhanceAppContext) => void
}
interface EnhanceAppContext {
app: App // Vue 3 app instance
router: Router // VitePress router instance
siteData: Ref<SiteData>
}
The theme entry file should export the theme as its default export:
// .vitepress/theme/index.js
import Layout from './Layout.vue'
export default {
Layout,
NotFound: () => 'custom 404', // <- this is a Vue 3 functional component
enhanceApp({ app, router, siteData }) {
// app is the Vue 3 app instance from `createApp()`. router is VitePress'
// custom router. `siteData` is a `ref` of current site-level metadata.
}
}
...where the Layout
component could look like this:
<!-- .vitepress/theme/Layout.vue -->
<template>
<h1>Custom Layout!</h1>
<Content /><!-- this is where markdown content will be rendered -->
</template>
The default export is the only contract for a custom theme. Inside your custom theme, it works just like a normal Vite + Vue 3 application. Do note the theme also needs to be SSR-compatible.
To distribute a theme, simply export the object in your package entry. To consume an external theme, import and re-export it from the custom theme entry:
// .vitepress/theme/index.js
import Theme from 'awesome-vitepress-theme'
export default Theme
Extending the Default Theme
If you want to extend and customize the default theme, you can import it from vitepress/theme
and augment it in a custom theme entry. Here are some examples of common customizations:
Registering Global Components
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
export default {
...DefaultTheme,
enhanceApp({ app }) {
// register global components
app.component('MyGlobalComponent' /* ... */)
}
}
Since we are using Vite, you can also leverage Vite's glob import feature to auto register a directory of components.
Customizing CSS
The default theme CSS is customizable by overriding root level CSS variables:
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import './custom.css'
export default DefaultTheme
/* .vitepress/theme/custom.css */
:root {
--c-brand: #646cff;
--c-brand-light: #747bff;
}
See default theme CSS variables that can be overridden.
Layout Slots
The default theme's <Layout/>
component has a few slots that can be used to inject content at certain locations of the page. Here's an example of injecting a component into the top of the sidebar:
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import MyLayout from './MyLayout.vue'
export default {
...DefaultTheme,
// override the Layout with a wrapper component that injects the slots
Layout: MyLayout
}
<!--.vitepress/theme/MyLayout.vue-->
<script setup>
import DefaultTheme from 'vitepress/theme'
const { Layout } = DefaultTheme
</script>
<template>
<Layout>
<template #sidebar-top>
My custom sidebar top content
</template>
</Layout>
</template>
Full list of slots available in the default theme layout:
navbar-search
sidebar-top
sidebar-bottom
page-top-ads
page-top
page-bottom
page-bottom-ads
- Only when
home: true
is enabled via frontmatter:home-hero
home-features
home-footer