Sidebar

Mr.Hope ... January 27, 2020 14:39 Layout
  • Sidebar
  • Layout
About 5 min

To enable the sidebar, use themeConfig.sidebar. The basic configuration expects an Array of links:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: ["/", "/page-a", "/page-b"],
  },
};
1
2
3
4
5
6

Each item of the array will eventually be rendered as a sidebar item.

You can omit the .md extension, and paths ending with / are inferred as */README.md.

Icon support is enabled in the sidebar by default, and the icon of the page will be displayed before the link in the sidebar (by reading icon field in frontmatter). It can be disabled by setting sidebarIcon to false in themeConfig.

The text for the link is automatically inferred (title field in frontmatter, then first header in the page). To explicitly specify the link text, use an array in form of [link, text].

Demo
// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      "/",
      "/page-a",
      ["/page-b", "This text will be the title of `page-b`"],
    ],
  },
};
1
2
3
4
5
6
7
8
9
10

The sidebar automatically displays links for headers in the current active page, nested under the link for the page itself. You can customize this behavior using themeConfig.sidebarDepth. The default depth(the max value) is 2, which extracts both h2 and h3 headers. Setting it to 0 disables the header links.

A page can also override this value via frontmatter:

---
sidebarDepth: 2
---
1
2
3

The sidebar only displays links for headers in the current active page. You can display all header links for every page with themeConfig.displayAllHeaders: true:

module.exports = {
  themeConfig: {
    displayAllHeaders: true, // Default: false
  },
};
1
2
3
4
5

By default, the nested header links and the hash in the URL are updated as the user scrolls to view the different sections of the page. This behavior can be disabled with the following theme config:

module.exports = {
  themeConfig: {
    activeHeaderLinks: false, // Default: true
  },
};
1
2
3
4
5

You can divide the sidebar into multiple groups by using Objects. By default, each group will be rendered into a menu that can be opened and collapsed. The menu item is each group link set by children in the group.

You can use prefix field to add a default path prefix to each link in the group, and icon field to add an icon to the group text.

Sidebar groups are collapsable by default. You can force a group to be always open with collapsable: false.

A sidebar group config also supports sidebarDepth field to override the default sidebar depth (2).

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      {
        // required, title of group
        title: "Group 1",
        // optional, icon of group
        icon: "bar",
        // optional, link of group title
        path: "/foo/",
        // optional, will be appended to each item link
        prefix: "/foo/",
        // optional, defaults to true
        collapsable: false,
        // optional, defaults to 2
        sidebarDepth: 2,
        // required, items of group
        children: ["/"],
      },
      {
        title: "Group 2",
        children: [
          /* ... */
        ],
      },
    ],
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Demo
// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      {
        title: "Get Started",
        icon: "creative",
        prefix: "/get-started/",
        collapsable: false,
        children: [
          "intro" /* /get-started/intro.html */,
          "install" /* /get-started/install.html */,
          "markdown" /* /get-started/markdown.html */,
        ],
      },
      {
        title: "Interface",
        icon: "skin",
        prefix: "/interface/",
        collapsable: false,
        children: [
          "darkmode" /* /interface/darkmode.html */,
          "theme-color" /* /interface/theme-color.html */,
          "icon" /* /interface/icon.html */,
          "others" /* /interface/others.html */,
        ],
      },
    ],
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

You can also nest Sidebar grouping:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      {
        title: "Group",
        prefix: "/",
        children: [
          "baz" /* /baz.html */,
          {
          title: "Sub Group 1",
          children: [
            "quz" /* /quz.html */,
            "xyzzy" /* /xyzzy.html */,
          ],
          title: "Sub Group 2",
          prefix: "corge/"
          children: [
            "fred" /* /corge/fred.html */,
            "grault" /* /corge/grault.html */,
          ],
          },
           "foo" /* /foo.html */,
        ],
      },
    ],
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Normally, you may want to use it with prefix to quickly restore the structure of the document.

For example, suppose you have a following directory structure:

.
├─ README.md
├─ contact.md
├─ about.md
├─ foo/
│   ├─ README.md
│   ├─ one.md
│   └─ two.md
└─ bar/
    ├─ README.md
    ├─ three.md
    └─ four.md
1
2
3
4
5
6
7
8
9
10
11
12

Then you can config:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      "/" /* / */,
      {
        title: "Foo",
        prefix: "/foo/",
        children: [
          "" /* /foo/ */,
          "one" /* /foo/one.html */,
          "two" /* /foo/two.html */,
        ],
      },
      {
        title: "Bar",
        prefix: "/bar/",
        children: [
          "" /* /bar/ */,
          "three" /* /bar/three.html */,
          "four" /* /bar/four.html */,
        ],
      },
      "/contact" /* /contact.html */,
      "/about" /* /about.html */,
    ],
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Note

Please pay special attention to the addition of / when configuring the sidebar. For performance considerations, we will assume that the user has correctly configured the sidebar, so we won’t perform any resolveing and verification on the path (such as traversing pages for comparison verification), but directly splicing and generating it.

Please pay attention to whether your configuration can be spliced into the correct path.

For example, bar/foo/ is expecting, while bar lacks a trailing / and foo isn’t with a prefix / resulting in barfoo/, or both are configured and an incorrect bar//foo is generated. They will cause parsing errors so the item won’t be rendered.

Tips

For the above reason, we will print any broken sidebar links in the console where the corresponding page cannot be found. This means that your misconfiguration can be easily tracked and corrected.

# Multiple Sidebars

To display different sidebars for different page groups, set an object for the sidebar in the format of path: config.

For example, if you have the following structure:

.
├─ README.md
├─ contact.md
├─ about.md
├─ foo/
│   ├─ README.md
│   ├─ one.md
│   └─ two.md
└─ bar/
    ├─ README.md
    ├─ three.md
    └─ four.md
1
2
3
4
5
6
7
8
9
10
11
12

You can define your sidebar for each section using below configuration:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: {
      "/foo/": [
        "" /* /foo/ */,
        "one" /* /foo/one.html */,
        "two" /* /foo/two.html */,
      ],

      "/bar/": [
        "" /* /bar/ */,
        "three" /* /bar/three.html */,
        "four" /* /bar/four.html */,
      ],

      // fallback
      "/": [
        "" /* / */,
        "contact" /* /contact.html */,
        "about" /* /about.html */,
      ],
    },
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

Note

You need to pay special attention to the order of object key declaration. Generally speaking, you should put the more precise path first, because VuePress will traverse the key names of the sidebar configuration to find the matching configuration. Once a key name is successfully matched with the current path, it will display the corresponding sidebar configuration.

In this case, the fallback sidebar must be defined last for this reason.

# Auto Sidebar for Single Pages

To automatically generate a sidebar that contains only the header links for the current page, you can use frontmatter on that page:

---
sidebar: auto
---
1
2
3

You can also enable it in all pages by using config:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: "auto",
  },
};
1
2
3
4
5
6

# Disabling the Sidebar

You can disable the sidebar on a specific page with YAML front matter:

---
sidebar: false
---
1
2
3

# Muti language support

In multi-language (opens new window) mode, you can also apply it to a specific locale:

// .vuepress/config.js
module.exports = {
  themeConfig: {
    "/zh/": {
      sidebar: [
        /* your config */
      ],: "auto",
    },
  },
};
1
2
3
4
5
6
7
8
9
10

# Blogger Information

If you have configured blog related options, you can configure themeConfig.blog.sidebarDisplay to decide whether to display the blogger’s name, avatar, and the number of articles and tags in the sidebar.

You can set 'mobile' to display only in mobile view, or set always to keep it displayed in the sidebar.

# sidebarConfig

We provide a sidebarConfig Helper function. You can import it from vuepress-theme-hope and wrap your navigation bar configuration to let the editor provide auto-completion and help you verify the sidebar configuration.

// .vuepress/sidebar.js
const { sidebarConfig } = require("vuepress-theme-hope");

module.exports = sidebarConfig(/* Your sidebar configuration */);
1
2
3
4

Tips

When you are spliting vuepress configuration into multiple parts, you can use this helper function to keep automatic completion and verification.

# Demo

Configuration of this documentation
// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: {
      "/guide/": [
        {
          title: "Get Started",
          icon: "creative",
          prefix: "get-started/",
          collapsable: false,
          children: ["intro", "install", "markdown"],
        },
        {
          title: "Interface",
          icon: "skin",
          prefix: "interface/",
          collapsable: false,
          children: ["darkmode", "theme-color", "icon", "others"],
        },
        {
          title: "Layout",
          icon: "layout",
          prefix: "layout/",
          collapsable: false,
          children: [
            "sidebar",
            "sidebar",
            {
              title: "Page",
              icon: "page",
              collapsable: false,
              children: ["page", "breadcrumb", "footer"],
            },
            "home",
            "slides",
          ],
        },
        {
          title: "Markdown enhance",
          icon: "markdown",
          prefix: "markdown/",
          collapsable: false,
          children: [
            "intro",
            "components",
            "align",
            "sup-sub",
            "footnote",
            "mark",
            "tex",
            "flowchart",
            "demo",
            "presentation",
            "external",
          ],
        },
        {
          title: "Features",
          icon: "discover",
          prefix: "feature/",
          collapsable: false,
          children: [
            "page-info",
            "comment",
            "copy-code",
            "photo-swipe",
            "copyright",
            "git",
            "encrypt",
            "pwa",
            "feed",
            "seo",
            "sitemap",
            "typescript",
          ],
        },
        {
          title: "Blog",
          icon: "layout",
          prefix: "blog/",
          collapsable: false,
          children: ["intro", "home", "category-and-tags"],
        },
      ],

      "/config/": [
        {
          title: "ThemeConfig",
          icon: "config",
          prefix: "theme/",
          collapsable: false,
          children: ["", "default", "feature", "plugin", "apperance"],
        },
        "page",
        "stylus",
        {
          title: "Plugins",
          icon: "plugin",
          prefix: "plugin/",
          collapsable: false,
          children: ["", "container", "copyright"],
        },
      ],

      "/basic/": [
        {
          title: "Markdown",
          icon: "markdown",
          prefix: "markdown/",
          collapsable: false,
          children: [
            "",
            "demo",
            {
              title: "Emoji",
              icon: "emoji",
              path: "emoji/",
              prefix: "emoji/",
              collapsable: false,
              children: ["people", "nature", "object", "place", "symbol"],
            },
          ],
        },
        {
          title: "VuePress",
          icon: "vue",
          prefix: "vuepress/",
          collapsable: false,
          children: [
            "",
            "file",
            "markdown",
            "plugin",
            "theme",
            "command",
            "case",
          ],
        },
      ],

      "/": ["", "guide/", "config/", "basic/", "FAQ/", "demo/"],
    },
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144