Navigation
Define your sidebar tabs, groups, and pages — plus navbar links.
Navigation
Navigation in cmdocs has two parts:
- Sidebar — controlled by the
navigationfield. Uses atabs → groups → pageshierarchy. - Navbar links — controlled by
navbar.links. The links shown across the top of the page.
Labels and paths
cmdocs separates display labels (what readers see) from URL paths (what appears in the address bar). This keeps URLs stable when you rename sections.
{
"navigation": {
"tabs": [
{
"label": "Documentation",
"path": "documentation",
"groups": [
{
"label": "Getting Started",
"pages": [
{ "file": "index" },
{ "file": "quickstart" }
]
}
]
}
]
}
}Key fields:
| Field | Where | Purpose |
|---|---|---|
label | tab, group | Display name (any text, multi-word OK) |
path | tab, page | URL segment — stable, kebab-case; changes here change URLs |
file | page | Source MDX file path (without .mdx) |
The shorthand tab/group fields and string-form pages still work (a deprecation warning is logged). Prefer label + path and the object page form for new projects.
How pages map to files
A page declaration decouples three concerns:
| Declaration | Source file | URL | Sidebar label |
|---|---|---|---|
{ "file": "index" } | index.mdx | /documentation | MDX frontmatter title |
{ "file": "quickstart" } | quickstart.mdx | /documentation/quickstart | MDX frontmatter title |
{ "file": "guides/setup" } | guides/setup.mdx | /documentation/guides/setup | MDX frontmatter title |
{ "file": "api/overview", "path": "api", "label": "API" } | api/overview.mdx | /documentation/api | "API" |
file— source file (where cmdocs reads from)path— URL path (tab-relative; defaults tofile)label— sidebar label (defaults to the MDX frontmattertitle)
Use the full object form whenever you need to decouple. For simple cases { "file": "quickstart" } is enough.
Tabs
Tabs are the top-level grouping. Each tab contains its own sidebar with groups.
Prop
Type
Tab with icon and description
{
"label": "API Reference",
"path": "api",
"description": "REST API endpoints",
"icon": "Code",
"groups": [
{
"label": "Endpoints",
"pages": [
{ "file": "api/auth" },
{ "file": "api/users" }
]
}
]
}When tabs have an icon or description, they render as a rich dropdown in the sidebar.
Why set path explicitly?
If you only provide label, cmdocs falls back to slugify(label) for the URL — e.g. "API Reference" becomes /api-reference. This works, but it means renaming the label would change the URL, breaking external links.
Setting path: "api" locks the URL in place. You can freely rename the label to "REST API" or "API Docs" without breaking anything.
Tab mode
{
"navigation": {
"tabMode": "auto"
}
}| Value | Behavior |
|---|---|
"auto" (default) | Tabs appear as a dropdown in the sidebar |
"top" | Tabs appear as a top bar above the sidebar |
Single-tab behavior
When you only have one tab with no customization, the tab selector is hidden and groups appear directly in the sidebar. Give the tab an icon or description to show the dropdown.
To disable tabs entirely, set theme.sidebar.tabs to false.
Groups
Groups are labeled sections inside a tab. They affect sidebar display only — they do not add URL segments.
{
"groups": [
{
"label": "Getting Started",
"pages": [
{ "file": "index" },
{ "file": "quickstart" },
{ "file": "installation" }
]
}
]
}Prop
Type
Pages appear in the sidebar in the order they're listed.
Pages
Each page is an object:
Prop
Type
The index page
A page with file: "index" (or path: "index") maps to the tab root URL (/documentation rather than /documentation/index).
Nested pages
A file path containing / automatically creates a collapsible subfolder in the sidebar:
{
"pages": [
{ "file": "guides/setup" },
{ "file": "guides/advanced" }
]
}→ both land under a guides/ subfolder in the sidebar.
Navbar links
The navbar.links array supports four link types.
1. Default link
A simple text link. Use this for blog or marketing pages.
{
"text": "Blog",
"href": "/blog",
"icon": "BookOpen",
"active": "nested-url"
}Prop
Type
2. Icon button
An icon-only button. Great for social links.
{
"type": "icon",
"text": "Discord",
"href": "https://discord.gg/your-server",
"icon": "MessageCircle",
"label": "Join our Discord",
"external": true
}Prop
Type
3. Styled button
A primary button. Use sparingly for CTAs.
{
"type": "button",
"text": "Get Started",
"href": "/documentation/quickstart",
"icon": "ArrowRight"
}Prop
Type
4. Dropdown menu
A menu containing multiple link items. Use this to group related links.
{
"type": "menu",
"text": "Resources",
"icon": "MoreHorizontal",
"items": [
{
"text": "Changelog",
"href": "/changelog",
"description": "See what's new"
},
{
"text": "GitHub",
"href": "https://github.com/owner/repo",
"external": true
}
]
}Prop
Type
Menu items
Each entry in items is a small object:
Prop
Type
Icons
Icons accept either:
- Lucide icon names — e.g.
"BookOpen","Rocket","MessageCircle". See the full list at lucide.dev/icons. - Emoji — e.g.
"📖","🚀","💬".
Icons work in both tabs and navbar links.
Validating your navigation
Run cmdocs check to verify:
- All page
filefields point to existing MDX files - No duplicate tab
pathvalues - Internal links in MDX and
navbar.linksresolve to real pages
npx @cmdoss/cmdocs checkThis catches typos before they hit production.
Full example
{
"navbar": {
"title": "My Docs",
"github": "https://github.com/owner/repo",
"links": [
{
"text": "Dashboard",
"href": "https://app.example.com",
"icon": "LayoutDashboard",
"external": true
},
{
"type": "icon",
"text": "Discord",
"href": "https://discord.gg/invite",
"icon": "MessageCircle",
"label": "Join Discord",
"external": true
},
{
"type": "menu",
"text": "Resources",
"items": [
{ "text": "Blog", "href": "/blog", "description": "Latest articles" },
{ "text": "Changelog", "href": "/changelog", "description": "What's new" }
]
}
]
},
"navigation": {
"tabMode": "auto",
"tabs": [
{
"label": "Documentation",
"path": "documentation",
"description": "Learn to use the platform",
"icon": "BookOpen",
"groups": [
{
"label": "Getting Started",
"pages": [
{ "file": "index" },
{ "file": "quickstart" }
]
},
{
"label": "Guides",
"pages": [
{ "file": "guides/setup" },
{ "file": "guides/advanced" }
]
}
]
},
{
"label": "API Reference",
"path": "api",
"description": "REST API documentation",
"icon": "Code",
"groups": [
{
"label": "Endpoints",
"pages": [
{ "file": "api/overview" },
{ "file": "api/authentication" }
]
}
]
}
]
}
}How is this guide?