Skip to main content
Version: 2.0.0-alpha.76 🚧

Sidebar

Creating a sidebar is useful to:

  • Group multiple related documents
  • Display a sidebar on each of those documents
  • Provide a paginated navigation, with next/previous button

To use sidebars on your Docusaurus site:

  1. Define a file that exports a sidebar object.
  2. Pass this object into the @docusaurus/plugin-docs plugin directly or via @docusaurus/preset-classic.
docusaurus.config.js
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
},
},
],
],
};

Default sidebar#

By default, Docusaurus automatically generates a sidebar for you, by using the filesystem structure of the docs folder:

sidebars.js
module.exports = {
mySidebar: [
{
type: 'autogenerated',
dirName: '.', // generate sidebar slice from the docs folder (or versioned_docs/<version>)
},
],
};

You can also define your sidebars explicitly.

Sidebar object#

A sidebar is a tree of sidebar items.

type Sidebar =
// Normal syntax
| SidebarItem[]
// Shorthand syntax
| Record<
string, // category label
SidebarItem[] // category items
>;

A sidebars file can contain multiple sidebar objects.

type SidebarsFile = Record<
string, // sidebar id
Sidebar
>;

Example:

sidebars.js
module.exports = {
mySidebar: [
{
type: 'category',
label: 'Getting Started',
items: ['doc1'],
},
{
type: 'category',
label: 'Docusaurus',
items: ['doc2', 'doc3'],
},
],
};

Notice the following:

  • There is a single sidebar mySidebar, containing 5 sidebar items
  • Getting Started and Docusaurus are sidebar categories
  • doc1, doc2 and doc3 are sidebar documents
tip

Use the shorthand syntax to express this sidebar more concisely:

sidebars.js
module.exports = {
mySidebar: {
'Getting started': ['doc1'],
Docusaurus: ['doc2', 'doc3'],
},
};

Using multiple sidebars#

You can create a sidebar for each set of markdown files that you want to group together.

tip

The Docusaurus site is a good example of using multiple sidebars:

Example:

sidebars.js
module.exports = {
tutorialSidebar: {
'Category A': ['doc1', 'doc2'],
},
apiSidebar: ['doc3', 'doc4'],
};
note

The keys tutorialSidebar and apiSidebar are sidebar technical ids and do not matter much.

When browsing:

  • doc1 or doc2: the tutorialSidebar will be displayed
  • doc3 or doc4: the apiSidebar will be displayed

A paginated navigation link documents inside the same sidebar with next and previous buttons.

Understanding sidebar items#

SidebarItem is an item defined in a Sidebar tree.

There are different types of sidebar items:

  • Doc: link to a doc page, assigning it to the sidebar
  • Ref: link to a doc page, without assigning it to the sidebar
  • Link: link to any internal or external page
  • Category: create a hierarchy of sidebar items
  • Autogenerated: generate a sidebar slice automatically

Doc: link to a doc#

Use the doc type to link to a doc page and assign that doc to a sidebar:

type SidebarItemDoc =
// Normal syntax
| {
type: 'doc';
id: string;
label: string; // Sidebar label text
}
// Shorthand syntax
| string; // docId shortcut

Example:

sidebars.js
module.exports = {
mySidebar: [
// Normal syntax:
{
type: 'doc',
id: 'doc1', // document id
label: 'Getting started', // sidebar label
},
// Shorthand syntax:
'doc2', // document id
],
};

The sidebar_label markdown frontmatter has a higher precedence over the label key in SidebarItemDoc.

note

Don't assign the same doc to multiple sidebars: use a ref instead.

Ref: link to a doc, without sidebar#

Use the ref type to link to a doc page without assigning it to a sidebar.

type SidebarItemRef = {
type: 'ref';
id: string;
};

Example:

sidebars.js
module.exports = {
mySidebar: [
{
type: 'ref',
id: 'doc1', // Document id (string).
},
],
};

When browsing doc1, Docusaurus will not display the mySidebar sidebar.

Link: link to any page#

Use the link type to link to any page (internal or external) that is not a doc.

type SidebarItemLink = {
type: 'link';
label: string;
href: string;
};

Example:

sidebars.js
module.exports = {
myLinksSidebar: [
// External link
{
type: 'link',
label: 'Facebook', // The link label
href: 'https://facebook.com', // The external URL
},
// Internal link
{
type: 'link',
label: 'Home', // The link label
href: '/', // The internal path
},
],
};

Category: create a hierarchy#

Use the category type to create a hierarchy of sidebar items.

type SidebarItemCategory = {
type: 'category';
label: string; // Sidebar label text.
items: SidebarItem[]; // Array of sidebar items.
// Category options:
collapsed: boolean; // Set the category to be collapsed or open by default
};

Example:

sidebars.js
module.exports = {
docs: [
{
type: 'category',
label: 'Guides',
collapsed: false,
items: [
'creating-pages',
{
type: 'category',
label: 'Docs',
items: ['introduction', 'sidebar', 'markdown-features', 'versioning'],
},
],
},
],
};
tip

Use the shorthand syntax when you don't need category options:

sidebars.js
module.exports = {
docs: {
Guides: [
'creating-pages',
{
Docs: ['introduction', 'sidebar', 'markdown-features', 'versioning'],
},
],
},
};

Collapsible categories#

For sites with a sizable amount of content, we support the option to expand/collapse a category to toggle the display of its contents. Categories are collapsible by default. If you want them to be always expanded, set themeConfig.sidebarCollapsible to false:

docusaurus.config.js
module.exports = {
themeConfig: {
sidebarCollapsible: false,
},
};

Expanded categories by default#

For docs that have collapsible categories, you may want more fine-grain control over certain categories. If you want specific categories to be always expanded, you can set collapsed to false:

sidebars.js
module.exports = {
docs: {
Guides: [
'creating-pages',
{
type: 'category',
label: 'Docs',
collapsed: false,
items: ['markdown-features', 'sidebar', 'versioning'],
},
],
},
};

Autogenerated: generate a sidebar#

Docusaurus can create a sidebar automatically from your filesystem structure: each folder creates a sidebar category.

An autogenerated item is converted by Docusaurus to a sidebar slice: a list of items of type doc and category.

type SidebarItemAutogenerated = {
type: 'autogenerated';
dirName: string; // Source folder to generate the sidebar slice from (relative to docs)
};

Docusaurus can generate a sidebar from your docs folder:

sidebars.js
module.exports = {
myAutogeneratedSidebar: [
{
type: 'autogenerated',
dirName: '.', // '.' means the current docs folder
},
],
};

You can also use multiple autogenerated items in a sidebar, and interleave them with regular sidebar items:

sidebars.js
module.exports = {
mySidebar: [
'intro',
{
type: 'category',
label: 'Tutorials',
items: [
'tutorial-intro',
{
type: 'autogenerated',
dirName: 'tutorials/easy', // Generate sidebar slice from docs/tutorials/easy
},
'tutorial-medium',
{
type: 'autogenerated',
dirName: 'tutorials/advanced', // Generate sidebar slice from docs/tutorials/hard
},
'tutorial-end',
],
},
{
type: 'autogenerated',
dirName: 'guides', // Generate sidebar slice from docs/guides
},
{
type: 'category',
label: 'Community',
items: ['team', 'chat'],
},
],
};

Autogenerated sidebar metadatas#

By default, the sidebar slice will be generated in alphabetical order (using files and folders names).

If the generated sidebar does not look good, you can assign additional metadatas to docs and categories.

For docs: use additional frontmatter:

docs/tutorials/tutorial-easy.md
+ ---
+ sidebar_label: Easy
+ sidebar_position: 2
+ ---
# Easy Tutorial
This is the easy tutorial!

For categories: add a _category_.json or _category_.yml file in the appropriate folder:

docs/tutorials/_category_.json
{
"label": "Tutorial",
"position": 3
}
docs/tutorials/_category_.yml
label: 'Tutorial'
position: 2.5 # float position is supported
collapsed: false # keep the category open by default
info

The position metadata is only used inside a sidebar slice: Docusaurus does not re-order other items of your sidebar.

Using number prefixes#

A simple way to order an autogenerated sidebar is to prefix docs and folders by number prefixes:

docs
├── 01-Intro.md
├── 02-Tutorial Easy
│   ├── 01-First Part.md
│   ├── 02-Second Part.md
│   └── 03-End.md
├── 03-Tutorial Hard
│   ├── 01-First Part.md
│   ├── 02-Second Part.md
│   ├── 03-Third Part.md
│   └── 04-End.md
└── 04-End.md

To make it easier to adopt, Docusaurus supports multiple number prefix patterns.

By default, Docusaurus will remove the number prefix from the doc id, title, label and url paths.

caution

Prefer using additional metadatas.

Updating a number prefix can be annoying, as it can require updating multiple existing markdown links:

docs/02-Tutorial Easy/01-First Part.md
- Check the [Tutorial End](../04-End.md);
+ Check the [Tutorial End](../05-End.md);

Customize the sidebar items generator#

You can provide a custom sidebarItemsGenerator function in the docs plugin (or preset) config:

docusaurus.config.js
module.exports = {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
sidebarItemsGenerator: async function ({
defaultSidebarItemsGenerator,
numberPrefixParser,
item,
version,
docs,
}) {
// Example: return an hardcoded list of static sidebar items
return [
{type: 'doc', id: 'doc1'},
{type: 'doc', id: 'doc2'},
];
},
},
],
],
};
tip

Re-use and enhance the default generator instead of writing a generator from scratch.

Add, update, filter, re-order the sidebar items according to your use-case:

docusaurus.config.js
// Reverse the sidebar items ordering (including nested category items)
function reverseSidebarItems(items) {
// Reverse items in categories
const result = items.map((item) => {
if (item.type === 'category') {
return {...item, items: reverseSidebarItems(item.items)};
}
return item;
});
// Reverse items at current level
result.reverse();
return result;
}
module.exports = {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
sidebarItemsGenerator: async function ({
defaultSidebarItemsGenerator,
...args
}) {
const sidebarItems = await defaultSidebarItemsGenerator(args);
return reverseSidebarItems(sidebarItems);
},
},
],
],
};

Hideable sidebar#

Using the enabled themeConfig.hideableSidebar option, you can make the entire sidebar hidden, allowing you to better focus your users on the content. This is especially useful when content consumption on medium screens (e.g. on tablets).

docusaurus.config.js
module.exports = {
themeConfig: {
// highlight-starrt
hideableSidebar: true,
},
};

Passing custom props#

To pass in custom props to a swizzled sidebar item, add the optional customProps object to any of the items:

{
type: 'doc',
id: 'doc1',
customProps: {
/* props */
}
}

Complex sidebars example#

Real-world example from the Docusaurus site:

sidebars.js
module.exports = {
docs: [
'introduction',
{
type: 'category',
label: 'Getting Started',
collapsed: false,
items: ['installation', 'configuration', 'typescript-support'],
},
{
type: 'category',
label: 'Guides',
items: [
'guides/creating-pages',
{
Docs: [
'guides/docs/introduction',
'guides/docs/create-doc',
'guides/docs/sidebar',
'guides/docs/versioning',
'guides/docs/markdown-features',
'guides/docs/multi-instance',
],
},
'blog',
{
type: 'category',
label: 'Markdown Features',
items: [
'guides/markdown-features/introduction',
'guides/markdown-features/react',
'guides/markdown-features/tabs',
'guides/markdown-features/code-blocks',
'guides/markdown-features/admonitions',
'guides/markdown-features/headings',
'guides/markdown-features/inline-toc',
'guides/markdown-features/assets',
'guides/markdown-features/plugins',
],
},
'styling-layout',
'static-assets',
'search',
'browser-support',
'deployment',
{
type: 'category',
label: 'Internationalization',
items: [
{
type: 'doc',
id: 'i18n/introduction',
label: 'Introduction',
},
{
type: 'doc',
id: 'i18n/tutorial',
label: 'Tutorial',
},
{
type: 'doc',
id: 'i18n/git',
label: 'Using Git',
},
{
type: 'doc',
id: 'i18n/crowdin',
label: 'Using Crowdin',
},
],
},
],
},
{
type: 'category',
label: 'Advanced Guides',
items: ['using-plugins', 'using-themes', 'presets'],
},
{
type: 'category',
label: 'Migrating from v1 to v2',
items: [
'migration/migration-overview',
'migration/migration-automated',
'migration/migration-manual',
'migration/migration-versioned-sites',
'migration/migration-translated-sites',
],
},
],
api: [
'cli',
'docusaurus-core',
'api/docusaurus.config.js',
'lifecycle-apis',
{
type: 'category',
label: 'Plugins',
items: [
'api/plugins/plugins-overview',
'api/plugins/plugin-content-docs',
'api/plugins/plugin-content-blog',
'api/plugins/plugin-content-pages',
'api/plugins/plugin-client-redirects',
'api/plugins/plugin-debug',
'api/plugins/plugin-google-analytics',
'api/plugins/plugin-google-gtag',
'api/plugins/plugin-ideal-image',
'api/plugins/plugin-pwa',
'api/plugins/plugin-sitemap',
],
},
{
type: 'category',
label: 'Themes',
items: [
'api/themes/themes-overview',
'api/themes/theme-configuration',
'api/themes/theme-classic',
'api/themes/theme-bootstrap',
'api/themes/theme-live-codeblock',
'api/themes/theme-search-algolia',
],
},
],
};
Last updated on by Sébastien Lorber