docusaurus/website/docs/guides/docs/sidebar.md
Joshua Chen c603056f66
docs: refactor API documentation (#5219)
* Refactor plugin-docs documentation

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Refactor theme-configuration

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Refactor plugin-blog docs

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Fix link

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* plugin-pages

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Minor change

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Interchange table columns

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Fixes

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Minor improvements

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Fix hash link

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Move blog front matter to API

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Add more blog documentation

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Update blog.md

* Update blog.md

* Update blog.md

* Update website/docs/blog.md

Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
Co-authored-by: slorber <lorber.sebastien@gmail.com>
2021-08-04 16:35:17 +02:00

695 lines
16 KiB
Markdown

---
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/<version>)
},
],
};
```
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';
<CodeBlock className="language-js" title="sidebars.js">
{require('!!raw-loader!@site/sidebars.js')
.default
.split('\n')
// remove comments
.map((line) => !['#','/*','*'].some(commentPattern => line.trim().startsWith(commentPattern)) && line)
.filter(Boolean)
.join('\n')}
</CodeBlock>
```