mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-04 01:09:20 +02:00
chore(v2): prepare v2.0.0-beta.1 release (#5004)
* beta.1 * v2.0.0-beta.1
This commit is contained in:
parent
7dc9fe839b
commit
8d8e5b67e8
101 changed files with 12264 additions and 142 deletions
|
@ -0,0 +1,633 @@
|
|||
---
|
||||
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-start
|
||||
sidebarPath: require.resolve('./sidebars.js'),
|
||||
// highlight-end
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## 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:
|
||||
collapsed: boolean; // Set the category to be collapsed or open by default
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="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**:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: {
|
||||
Guides: [
|
||||
'creating-pages',
|
||||
{
|
||||
Docs: ['introduction', 'sidebar', 'markdown-features', 'versioning'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
#### Collapsible categories {#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`:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
themeConfig: {
|
||||
// highlight-start
|
||||
sidebarCollapsible: false,
|
||||
// highlight-end
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
#### Expanded categories by default {#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`:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: {
|
||||
Guides: [
|
||||
'creating-pages',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Docs',
|
||||
collapsed: false,
|
||||
items: ['markdown-features', 'sidebar', 'versioning'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 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
|
||||
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>
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue