Skip to main content
Version: 2.0.0-beta.5

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.

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

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.

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.

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    },  ],};

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:  collapsible: boolean; // Set the category to be collapsible  collapsed: boolean; // Set the category to be initially collapsed or open by default};

Example:

sidebars.js
module.exports = {  docs: [    {      type: 'category',      label: 'Guides',      collapsible: true,      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#

We support the option to expand/collapse categories. Categories are collapsible by default, but you can disable collapsing with collapsible: false.

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

To make all categories non-collapsible by default, set the sidebarCollapsible option in plugin-docs to false:

docusaurus.config.js
module.exports = {  presets: [    [      '@docusaurus/preset-classic',      {        docs: {          sidebarCollapsible: false,        },      },    ],  ],};
note

The option in sidebars.js takes precedence over plugin configuration, so it is possible to make certain categories collapsible when sidebarCollapsible is set to false globally.

Expanded categories by default#

Collapsible categories are collapsed by default. If you want them to be expanded on first render, 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'],      },    ],  },};

Similar to collapsible, you can also set the global configuration options.sidebarCollapsed to false. Individual collapsed options in sidebars.js will still take precedence over this configuration.

docusaurus.config.js
module.exports = {  presets: [    [      '@docusaurus/preset-classic',      {        docs: {          sidebarCollapsed: false,        },      },    ],  ],};
caution

When a category has collapsed: true but collapsible: false (either through sidebars.js or through plugin configuration), the latter takes precedence and the category is still rendered as expanded.

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: Easysidebar_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 supportedcollapsible: true # make the category collapsiblecollapsed: 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: {    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',        'playground',        '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',            'guides/markdown-features/math-equations',            'guides/markdown-features/head-metadatas',          ],        },        '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',      ],    },  ],};