VuePressVuePress
  • Introduction
  • Getting Started
  • Configuration
  • Page
  • Markdown
  • Assets
  • I18n
  • Deployment
  • Theme
  • Plugin
  • Bundler
  • Migrating from v1
  • Troubleshooting
  • Core

    • CLI
    • Config
    • Frontmatter
    • Built-in Components
    • Plugin API
    • Theme API
    • Client API
    • Node API
  • Bundlers

    • Vite
    • Webpack
  • Ecosystem

    • Default Theme
    • Plugins
  • Advanced

    • Architecture
    • Writing a Plugin
    • Writing a Theme
    • Cookbook
  • Resources

    • Ecosystem
    • MarketPlace
    • Contributing Guide
  • Changelog
  • v1.x
  • v0.x
  • English
  • 简体中文
GitHub
  • Introduction
  • Getting Started
  • Configuration
  • Page
  • Markdown
  • Assets
  • I18n
  • Deployment
  • Theme
  • Plugin
  • Bundler
  • Migrating from v1
  • Troubleshooting
  • Core

    • CLI
    • Config
    • Frontmatter
    • Built-in Components
    • Plugin API
    • Theme API
    • Client API
    • Node API
  • Bundlers

    • Vite
    • Webpack
  • Ecosystem

    • Default Theme
    • Plugins
  • Advanced

    • Architecture
    • Writing a Plugin
    • Writing a Theme
    • Cookbook
  • Resources

    • Ecosystem
    • MarketPlace
    • Contributing Guide
  • Changelog
  • v1.x
  • v0.x
  • English
  • 简体中文
GitHub
  • Advanced

    • Architecture
    • Writing a Plugin
    • Writing a Theme
  • Cookbook

    • Introduction
    • Usage of Client Config
    • Adding Extra Pages
    • Making a Theme Extendable
    • Passing Data to Client Code
    • Markdown and Vue SFC
    • Resolving Routes

Writing a Theme

Tips

Before reading this guide, you'd better learn the guide of Writing a Plugin first.

Create a Theme

A VuePress theme is a special plugin, which should satisfy the Theme API. Like plugins, a theme should also be a Theme Object or a Theme Function, and could be wrapped with a function to receive options:

import { getDirname, path } from 'vuepress/utils'

const __dirname = getDirname(import.meta.url)

const fooTheme = (options) =>
  // returns a theme object
  ({
    name: 'vuepress-theme-foo',

    // path to the client config of your theme
    clientConfigFile: path.resolve(__dirname, 'client.js'),

    // set custom dev / build template
    // if the template is not specified, the default template
    templateBuild: path.resolve(__dirname, 'templates/build.html'),
    templateDev: path.resolve(__dirname, 'templates/dev.html'),

    // use plugins
    plugins: [
      // ...
    ],

    // other plugin APIs are also available
  })

const barTheme =
  (options) =>
  // returns a theme function
  (app) => ({
    name: 'vuepress-theme-bar',
    // ...
  })

Then, create theme's client config file client.js :

import { defineClientConfig } from 'vuepress/client'
import Layout from './layouts/Layout.vue'
import NotFound from './layouts/NotFound.vue'

export default defineClientConfig({
  layouts: {
    Layout,
    NotFound,
  },
})

The layouts field declares the layouts provided by your theme. A theme must provide at least two layouts: Layout and NotFound. The former is to provide default layout for common pages, while the latter is to provide layout for 404-not-found page.

The Layout layout should contain the Content component to display the markdown content:

<template>
  <div>
    <Content />
  </div>
</template>

The NotFound layout will be used for the 404.html page:

<template>
  <div>404 Not Found</div>
</template>

You can provide more layouts, and users can change layout via layout frontmatter.

Publish to NPM

Also, there are some conventions for theme in package.json:

{
  "name": "vuepress-theme-foo",
  "keywords": ["vuepress-theme"]
}
  • Set name to follow the naming convention: vuepress-theme-xxx or @org/vuepress-theme-xxx, which should be consistent with the name field of the Theme Object.
  • Set keywords to include vuepress-theme, so that users can search your theme on NPM.
Edit this page on GitHub
Last Updated:: 8/31/24, 7:59 AM
Contributors: meteorlxy, Mr.Hope, Xinyu Liu
Prev
Writing a Plugin