Skip to content

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.js

A most basic custom theme configuration file looks like this:

javascript
// .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.

  1. Create Layout File

    Create a Vue component in the theme directory, such as MyLayout.vue.

    .vitepress
    └── theme
        ├── index.js
        └── MyLayout.vue
  2. Write 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>
  3. 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.

vue
<!-- .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:

  1. In Layout Component: Use <style> tags directly in .vue files.

  2. 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.

Content is for learning and research only.