Docusaurus Nav Command
Converts a Docusaurus sidebars.js file into Mintlify navigation JSON, ready to paste into docs.json.
Usage
writechoice docusaurus nav <file> [options]
Arguments
| Argument | Description |
|---|---|
<file> | Path to the Docusaurus sidebars.js (or sidebars.ts) file |
Options
| Option | Description | Default |
|---|---|---|
--prefix <path> | Prepend a path prefix to every page ID (e.g. mintlify) | — |
--docs-dir <dir> | Docs folder used to expand autogenerated items | docs/ next to sidebars.js |
-o, --output <file> | Write result to this file instead of stdout | nav.json |
--links-dir <dir> | Directory for type: "link" sidebar entry stubs | links |
--no-links | Drop type: "link" entries instead of stubbing them (old behavior) | false |
--quiet | Suppress terminal output | false |
Output Format
The output structure depends on how many sidebars are defined:
| Sidebars count | Output structure |
|---|---|
| One sidebar | { anchors: [{ anchor, pages }] } |
| Multiple sidebars | { tabs: [{ tab, pages }] } |
This JSON is designed to be merged into or used as the navigation value in docs.json.
Supported Item Types
| Docusaurus type | Handled as |
|---|---|
| String (bare doc ID) | Page path string |
{ type: 'doc', id } | Page path string |
{ type: 'category', label, items } | { group, pages } object |
{ type: 'autogenerated', dirName } | Expanded by reading the docs folder |
{ type: 'link', label, href } | Stubbed as a page (see below), unless --no-links |
{ type: 'html' } | Skipped (decorative separators, no destination to preserve) |
{ type: 'ref' } | Treated as a doc ID |
type: "link" stubs
A Docusaurus sidebar link entry (an external URL, or an absolute in-site path like /docs/proxy/some_page) has no direct Mintlify navigation equivalent — a plain page string can only point at a converted .mdx file. By default this command writes a small stub .mdx file per link under --links-dir (same mechanism wcc readme nav uses for readme.io's external sidebar links) and uses that stub's path as the page entry, so the link survives the conversion instead of silently disappearing:
// sidebars.js
{ type: "link", label: "Configuration Reference", href: "/docs/proxy/auto_routing" }
produces links/configuration-reference.mdx:
---
title: "Configuration Reference"
url: "/docs/proxy/auto_routing"
---
and the nav entry becomes the string "links/configuration-reference". Mintlify renders a page with a url frontmatter field as a link to that URL. An entry with no href is dropped (nothing to link to). Pass --no-links to restore the old behavior of dropping every link entry.
Autogenerated expansion
When a sidebar contains { type: 'autogenerated', dirName: 'faq' }, the command walks the corresponding directory in the docs folder and builds the equivalent structure:
- Reads
_category_.jsonin subdirectories for folderlabelandposition - Reads
sidebar_positionfrom each file's frontmatter for ordering - Falls back to alphabetical sort when positions are equal or absent
- Skips files and directories whose names start with
_
Examples
# Convert sidebars.js, write result to nav.json
writechoice docusaurus nav ./my-site/sidebars.js
# Add a prefix so all page IDs start with "mintlify/"
writechoice docusaurus nav ./my-site/sidebars.js --prefix mintlify
# Write to a specific output file
writechoice docusaurus nav ./my-site/sidebars.js -o navigation.json
# Specify docs folder explicitly
writechoice docusaurus nav ./my-site/sidebars.js --docs-dir ./my-site/docs --prefix mintlify
Example Input → Output
sidebars.js:
module.exports = {
tutorialSidebar: [
'intro',
{
type: 'category',
label: 'Tutorial',
items: [
'tutorial/basics',
'tutorial/deploy',
],
},
],
};
nav.json output (with --prefix mintlify):
{
"anchors": [
{
"anchor": "Tutorial Sidebar",
"pages": [
"mintlify/intro",
{
"group": "Tutorial",
"pages": [
"mintlify/tutorial/basics",
"mintlify/tutorial/deploy"
]
}
]
}
]
}
Multiple sidebars produce tabs instead of anchors:
{
"tabs": [
{
"tab": "Docs",
"pages": [...]
},
{
"tab": "API",
"pages": [...]
}
]
}
Typical Workflow
# 1. Convert all files
writechoice docusaurus convert ./my-docusaurus-site
# 2. Rename files to match their frontmatter slug/id
writechoice docusaurus slugify ./mintlify
# 3. Generate Mintlify navigation
writechoice docusaurus nav ./my-docusaurus-site/sidebars.js --prefix mintlify
# 4. Inspect nav.json and merge into docs.json
cat nav.json
Notes
- The command loads
sidebars.jsusingrequire(). If that fails (e.g. TypeScript or ESM syntax), it falls back to a text-based parser that handles common patterns. - Sidebar key names are converted from
camelCase/snake_caseto Title Case for theanchor/tablabel. htmlitems are silently skipped — they have no Mintlify equivalent.linkitems are stubbed by default (see above) or skipped with--no-links.