---
title: navigation
description: The exact shape and limits of the navigation tree.
---

The schema-level reference. For how to use these shapes, see
[Navigation](/docs/authoring/navigation).

## Shape

<ParamField name="navigation.tabs" type="Tab[]" required>
  At least one tab.
</ParamField>

<ParamField name="tabs[].label" type="string" required>
  Tab label, 1–100 characters.
</ParamField>

<ParamField name="tabs[].groups" type="Group[]" required>
  At least one group.
</ParamField>

<ParamField name="groups[].label" type="string" required>
  Group label, 1–100 characters.
</ParamField>

<ParamField name="groups[].pages" type="(PageRef | Group | ApiRef)[]" required>
  At least one entry.
</ParamField>

## `PageRef`

A bare string naming a page id. Grammar:
`^[A-Za-z0-9_-]+(?:/[A-Za-z0-9_-]+)*$`

The grammar constrains the string you write; it does not define which ids exist. A page
id is derived from the file by these rules:

| File | Page id |
|---|---|
| `guide/intro.mdx` | `guide/intro` |
| `Guide/Intro.mdx` | `guide/intro` — every segment is slugified |
| `derived/index.mdx` | `derived` — a nested index collapses to its directory |
| `index.mdx` | `index` — the site root |
| any file with `slug: custom-route` | `custom-route` — frontmatter wins outright |
| `_draft.mdx`, or anything under a dot-prefixed directory | none — not loaded |

The grammar permits uppercase, so `"Guide/Intro"` is a legal string that names no page.
`reed check` reports the mismatch, naming both the written `PageRef` and the file's real
id.

## `ApiRef`

<ParamField name="label" type="string" required>
  Label for the generated section.
</ParamField>

<ParamField name="api" type="true" required>
  Marks the entry as spec-generated.
</ParamField>

<ParamField name="spec" type="string">
  A key from `api.specs`. Required unless `api.specs` has exactly one entry.
</ParamField>

Structural rules: an `ApiRef` must be the sole page of its group, and that group the sole
group of its tab.

## Limits

| Limit | Value |
|---|---|
| Minimum tabs | 1 |
| Minimum groups per tab | 1 |
| Minimum pages per group | 1 |
| Maximum nesting depth | 5 |

A `PageRef` that resolves to no file is an error, so navigation can never point at a page
that does not exist.
