nav.yaml
nav.yaml defines the navigation structure of your documentation site. It is the single source of truth for sidebar order, hierarchy, and labels — completely decoupled from file names and folder layout.
Shorthand format
The shorthand format covers the majority of nav entries. A leaf is a label mapped to a file path; a group is a label mapped to a nested list.
# Leaf: a link to a page
- Introduction: index.md
# Group: a collapsible section with no landing page
- Getting Started:
- Installation: getting-started/installation.md
- First Steps: getting-started/first-steps.md
# Groups nest to any depth
- Reference:
- API:
- Authentication: reference/api/auth.md
- Endpoints: reference/api/endpoints.md
- CLI: reference/cli.md
Paths are relative to the docs/ directory. Labels are independent of page titles — what you write here is what appears in the sidebar, regardless of what the page's h1 says.
Rich format
When you need a section that has both a landing page and children, or when you want to attach metadata to a nav node, use the rich (structured map) format. A rich entry is recognised by the presence of a label: key.
- label: Blog
url: blog/index.md
items:
- label: "2026"
collapsed: true
items:
- Just doing the thing: blog/2026/just-doing-the-thing.md
- Another post: blog/2026/another.md
- label: "2025"
collapsed: true
items:
- Year in review: blog/2025/year-in-review.md
Node type is inferred from which fields are present — there is no explicit type discriminator:
| Fields present | Result |
|---|---|
url + items |
Section — clickable header with expandable children |
items only |
Group — non-clickable header with expandable children |
url only |
Leaf — plain page link, no children |
heading: true |
Heading — non-clickable visual divider, no link or children |
Field reference
| Field | Type | Description |
|---|---|---|
label |
string | Text displayed in the sidebar. Required in rich format. |
url |
string | Path to a .md file, relative to docs/. Makes the entry a clickable link. |
heading |
bool | When true, renders as a non-clickable visual divider. Cannot be combined with url or items. |
collapsed |
bool | When true, the group or section starts collapsed. Default: false. |
class |
string | One or more extra CSS classes added to the nav node's <li> element. Useful for custom styling. |
items |
list | Child entries. Accepts any mix of shorthand and rich entries. |
Mixing formats
Shorthand and rich entries can be mixed freely at any level. A common pattern is a rich entry at the top level (to attach a URL or metadata) with shorthand children:
- label: Reference
heading: true
- label: API
url: api/index.md
class: nav-api
items:
- Authentication: api/auth.md
- Endpoints: api/endpoints.md
- Errors: api/errors.md
- label: Changelog
collapsed: true
items:
- v2.0: changelog/v2.md
- v1.x: changelog/v1.md
Includes
Large sites can split navigation across multiple files using !include:
# nav.yaml
- Introduction: index.md
- Getting Started:
- Installation: getting-started/installation.md
- Reference: !include nav/reference.yaml
- Guides: !include nav/guides.yaml
# nav/reference.yaml
- API: reference/api.md
- CLI: reference/cli.md
Included files are resolved relative to the file that includes them. Includes can be nested. A label before !include wraps the included entries in a section; an empty label ('': !include other.yaml) inlines them directly at the current level.
Rules
Files not in nav.yaml are still built and accessible by direct URL, but do not appear in the sidebar. This is intentional — you can have unlisted pages (changelogs, generated reference, etc.) without cluttering the navigation.
Nav entries pointing to missing files produce a build warning with the exact path. They do not cause the build to fail.
Ordering is explicit. There are no weight or order frontmatter fields. The order in nav.yaml is the order in the sidebar. Period.
Integration with braised.yaml
nav.yaml can be declared as an external file (the default) or inline in braised.yaml:
# braised.yaml
nav: nav.yaml # external file
# or inline
nav:
- Introduction: index.md
- Guide: guide.md
For any site larger than a few pages, an external file is strongly recommended.
Active state
Braised automatically marks the current page and all its ancestor sections as active when rendering the sidebar. Styling the active state is handled in your theme CSS:
.nav-link.active { font-weight: bold; }
.nav-section.active { color: var(--accent); }