VitePress Custom Theme
While VitePress's default theme is powerful and configurable, sometimes you may need a completely unique design. VitePress allows you to take complete control of your site's UI by creating a custom theme.
Theme Entry Point
To use a custom theme, you need to create a theme directory under .vitepress and add an index.js or index.ts file to it. This file is your custom theme's entry point.
.vitepress
└── theme
└── index.jsA most basic custom theme configuration file looks like this:
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
export default {
// Inherit the default theme if you only want to extend it
...DefaultTheme,
// Layout is required, it will be used as the root component for each page
Layout: () => {
// ... return your custom layout component here
}
}Layout Component
The Layout component is the core of a custom theme. It's a Vue component responsible for rendering the overall structure of the page, including the header, footer, sidebar, and most importantly—the Markdown content.
Create Layout File
Create a Vue component in the
themedirectory, such asMyLayout.vue..vitepress └── theme ├── index.js └── MyLayout.vueWrite Layout Component
VitePress provides a special
<Content />component that you must include in your layout. It's responsible for rendering the current page's Markdown content.vue<!-- .vitepress/theme/MyLayout.vue --> <template> <div> <header> <h1>My Custom Website</h1> </header> <main> <Content /> </main> <footer> <p>Copyright © 2023</p> </footer> </div> </template>Register Layout in Theme
Now, import and use your layout component in
index.js.javascript// .vitepress/theme/index.js import DefaultTheme from 'vitepress/theme' import MyLayout from './MyLayout.vue' export default { ...DefaultTheme, // Inherit default theme styles and some underlying logic Layout: MyLayout }
Accessing Page Data
In your custom layout or any custom component, you may need to access the current page's data, such as frontmatter, title, path, etc. VitePress provides the useData composable function to achieve this.
<!-- .vitepress/theme/MyLayout.vue -->
<script setup>
import { useData } from 'vitepress'
const { page, frontmatter } = useData()
</script>
<template>
<div>
<h1>{{ frontmatter.title }}</h1>
<p>{{ frontmatter.description }}</p>
<Content />
</div>
</template>Adding Styles
You can add styles to your custom theme in several ways:
In Layout Component: Use
<style>tags directly in.vuefiles.Import CSS Files: Import a CSS file directly in your
theme/index.js.javascript// .vitepress/theme/index.js import DefaultTheme from 'vitepress/theme' import MyLayout from './MyLayout.vue' import './custom.css' // Import custom styles export default { Layout: MyLayout, // ... }
Creating a custom theme provides extremely high freedom, but it also means you need to handle more details yourself, such as navigation, responsive layout, etc. For most users who just want to make some adjustments, extending the default theme (next chapter content) might be a simpler and more efficient choice.