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:
- Define a file that exports a sidebar object.
- Pass this object into the
@docusaurus/plugin-docs
plugin directly or via@docusaurus/preset-classic
.
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:
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:
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
andDocusaurus
are sidebar categoriesdoc1
,doc2
anddoc3
are sidebar documents
tip
Use the shorthand syntax to express this sidebar more concisely:
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.
Example:
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
ordoc2
: thetutorialSidebar
will be displayeddoc3
ordoc4
: theapiSidebar
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:
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:
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:
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: collapsible: boolean; // Set the category to be collapsible collapsed: boolean; // Set the category to be initially collapsed or open by default};
Example:
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:
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
.
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
:
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
:
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.
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.
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:
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:
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:
---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:
{ "label": "Tutorial", "position": 3}
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:
- 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:
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:
// 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).
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:
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', ], }, ],};