The document is only used for theme display, please go to the official site for the latest Vuepress documentation

Writing a Theme

TIP

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 can also be a Theme Object or a Theme Function.

const { path } = require('@vuepress/utils')

const fooTheme = {
  name: 'vuepress-theme-foo',
  layouts: {
    Layout: path.resolve(__dirname, 'layouts/Layout.vue'),
    404: path.resolve(__dirname, 'layouts/404.vue'),
  },
  // ...
}
1
2
3
4
5
6
7
8
9
10
const { path } = require('@vuepress/utils')

const fooTheme = (options, app) => {
  return {
    name: 'vuepress-theme-foo',
    layouts: {
      Layout: path.resolve(__dirname, 'layouts/Layout.vue'),
      404: path.resolve(__dirname, 'layouts/404.vue'),
    },
    // ...
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

The layouts field declares the layouts provided by your theme.

A theme must provide at least two layouts: Layout and 404.

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

<template>
  <div>
    <Content />
  </div>
</template>
1
2
3
4
5

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

<template>
  <div>404 Not Found</div>
</template>
1
2
3

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

Publish to NPM

The typical structure of a theme package is as follow:

vuepress-theme-foo
├─ lib
│  ├─ layouts
│  │  ├─ Layout.vue
│  │  └─ 404.vue
│  └─ index.js
└─ package.json
1
2
3
4
5
6
7

Theme Entry

The lib/index.js file is the theme entry, which should export the theme directly:

module.exports = fooTheme
1
export default fooTheme
1

TIP

Notice that the theme entry will be loaded in Node, so it should be in CommonJS format.

If you are using ESM format, you'll need to use babelopen in new window or typescriptopen in new window to transpile it into CommonJS.

package.json

The package.jsonopen in new window file is required to publish a package to NPM:

{
  "name": "vuepress-theme-foo",
  "version": "1.0.0",
  "keywords": [
    "vuepress-theme",
  ],
  "main": "lib/index.js",
  "files": [
    "lib"
  ]
}
1
2
3
4
5
6
7
8
9
10
11
  • Set name to follow the naming convention: vuepress-theme-xxx or @org/vuepress-theme-xxx.
  • Set keywords to include vuepress-theme, so that users can search your theme on NPM.
  • Set main to the theme entry file.
  • Set files to only publish those files inside lib directory.