--- id: sidebar title: Sidebar slug: /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](#sidebar-object). 1. Pass this object into the `@docusaurus/plugin-docs` plugin directly or via `@docusaurus/preset-classic`. ```js title="docusaurus.config.js" module.exports = { presets: [ [ '@docusaurus/preset-classic', { docs: { // highlight-next-line sidebarPath: require.resolve('./sidebars.js'), }, }, ], ], }; ``` ## Default sidebar By default, Docusaurus [automatically generates a sidebar](#sidebar-item-autogenerated) for you, by using the filesystem structure of the `docs` folder: ```js title="sidebars.js" module.exports = { mySidebar: [ { type: 'autogenerated', dirName: '.', // generate sidebar slice from the docs folder (or versioned_docs/) }, ], }; ``` You can also define your sidebars explicitly. ## Sidebar object {#sidebar-object} A sidebar is a **tree of [sidebar items](#understanding-sidebar-items)**. ```typescript type Sidebar = // Normal syntax | SidebarItem[] // Shorthand syntax | Record< string, // category label SidebarItem[] // category items >; ``` A sidebars file can contain **multiple sidebar objects**. ```typescript type SidebarsFile = Record< string, // sidebar id Sidebar >; ``` Example: ```js title="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](#understanding-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: ```js title="sidebars.js" module.exports = { mySidebar: { 'Getting started': ['doc1'], Docusaurus: ['doc2', 'doc3'], }, }; ``` ::: ## Using multiple sidebars {#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: - [Docs](../../introduction.md) - [API](../../cli.md) ::: Example: ```js title="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 {#understanding-sidebar-items} `SidebarItem` is an item defined in a Sidebar tree. There are different types of sidebar items: - **[Doc](#sidebar-item-doc)**: link to a doc page, assigning it to the sidebar - **[Ref](#sidebar-item-ref)**: link to a doc page, without assigning it to the sidebar - **[Link](#sidebar-item-link)**: link to any internal or external page - **[Category](#sidebar-item-category)**: create a hierarchy of sidebar items - **[Autogenerated](#sidebar-item-autogenerated)**: generate a sidebar slice automatically ### Doc: link to a doc {#sidebar-item-doc} Use the `doc` type to link to a doc page and assign that doc to a sidebar: ```typescript type SidebarItemDoc = // Normal syntax | { type: 'doc'; id: string; label: string; // Sidebar label text } // Shorthand syntax | string; // docId shortcut ``` Example: ```js title="sidebars.js" module.exports = { mySidebar: [ // Normal syntax: // highlight-start { type: 'doc', id: 'doc1', // document id label: 'Getting started', // sidebar label }, // highlight-end // Shorthand syntax: // highlight-start 'doc2', // document id // highlight-end ], }; ``` 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](#sidebar-item-ref) instead. ::: ### Ref: link to a doc, without sidebar {#sidebar-item-ref} Use the `ref` type to link to a doc page without assigning it to a sidebar. ```typescript type SidebarItemRef = { type: 'ref'; id: string; }; ``` Example: ```js title="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 {#sidebar-item-link} Use the `link` type to link to any page (internal or external) that is not a doc. ```typescript type SidebarItemLink = { type: 'link'; label: string; href: string; }; ``` Example: ```js title="sidebars.js" module.exports = { myLinksSidebar: [ // highlight-start // External link { type: 'link', label: 'Facebook', // The link label href: 'https://facebook.com', // The external URL }, // highlight-end // highlight-start // Internal link { type: 'link', label: 'Home', // The link label href: '/', // The internal path }, // highlight-end ], }; ``` ### Category: create a hierarchy {#sidebar-item-category} Use the `category` type to create a hierarchy of sidebar items. ```typescript 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: ```js title="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**: ```js title="sidebars.js" module.exports = { docs: { Guides: [ 'creating-pages', { Docs: ['introduction', 'sidebar', 'markdown-features', 'versioning'], }, ], }, }; ``` ::: #### Collapsible categories {#collapsible-categories} We support the option to expand/collapse categories. Categories are collapsible by default, but you can disable collapsing with `collapsible: false`. ```js title="sidebars.js" module.exports = { docs: [ { type: 'category', label: 'Guides', items: [ 'creating-pages', { type: 'category', // highlight-next-line 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`: ```js title="docusaurus.config.js" module.exports = { presets: [ [ '@docusaurus/preset-classic', { docs: { // highlight-next-line 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 {#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`: ```js title="sidebars.js" module.exports = { docs: { Guides: [ 'creating-pages', { type: 'category', label: 'Docs', // highlight-next-line 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. ```js title="docusaurus.config.js" module.exports = { presets: [ [ '@docusaurus/preset-classic', { docs: { // highlight-next-line 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 {#sidebar-item-autogenerated} 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`. ```typescript 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: ```js title="sidebars.js" module.exports = { myAutogeneratedSidebar: [ // highlight-start { type: 'autogenerated', dirName: '.', // '.' means the current docs folder }, // highlight-end ], }; ``` You can also use **multiple `autogenerated` items** in a sidebar, and interleave them with regular sidebar items: ```js title="sidebars.js" module.exports = { mySidebar: [ 'intro', { type: 'category', label: 'Tutorials', items: [ 'tutorial-intro', // highlight-start { type: 'autogenerated', dirName: 'tutorials/easy', // Generate sidebar slice from docs/tutorials/easy }, // highlight-end 'tutorial-medium', // highlight-start { type: 'autogenerated', dirName: 'tutorials/advanced', // Generate sidebar slice from docs/tutorials/hard }, // highlight-end 'tutorial-end', ], }, // highlight-start { type: 'autogenerated', dirName: 'guides', // Generate sidebar slice from docs/guides }, // highlight-end { type: 'category', label: 'Community', items: ['team', 'chat'], }, ], }; ``` #### Autogenerated sidebar metadatas {#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: ```md title="docs/tutorials/tutorial-easy.md" {1-4} --- 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: ```json title="docs/tutorials/_category_.json" { "label": "Tutorial", "position": 3 } ``` ```yaml title="docs/tutorials/_category_.yml" label: 'Tutorial' position: 2.5 # float position is supported collapsible: true # make the category collapsible 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: ```bash 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](#autogenerated-sidebar-metadatas)**. Updating a number prefix can be annoying, as it can require **updating multiple existing markdown links**: ```diff title="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: ```js title="docusaurus.config.js" module.exports = { plugins: [ [ '@docusaurus/plugin-content-docs', { // highlight-start 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'}, ]; }, // highlight-end }, ], ], }; ``` :::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: ```js title="docusaurus.config.js" // highlight-start // 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; } // highlight-end module.exports = { plugins: [ [ '@docusaurus/plugin-content-docs', { // highlight-start sidebarItemsGenerator: async function ({ defaultSidebarItemsGenerator, ...args }) { const sidebarItems = await defaultSidebarItemsGenerator(args); return reverseSidebarItems(sidebarItems); }, // highlight-end }, ], ], }; ``` ::: ## Hideable sidebar {#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). ```js title="docusaurus.config.js" module.exports = { themeConfig: { // highlight-start hideableSidebar: true, // highlight-end }, }; ``` ## Passing custom props {#passing-custom-props} To pass in custom props to a swizzled sidebar item, add the optional `customProps` object to any of the items: ```js { type: 'doc', id: 'doc1', customProps: { /* props */ } } ``` ## Complex sidebars example {#complex-sidebars-example} Real-world example from the Docusaurus site: ```mdx-code-block import CodeBlock from '@theme/CodeBlock'; {require('!!raw-loader!@site/sidebars.js') .default .split('\n') // remove comments .map((line) => !['#','/*','*'].some(commentPattern => line.trim().startsWith(commentPattern)) && line) .filter(Boolean) .join('\n')} ```