# Navigation and the sidebar

The sidebar is data, not markup — `src/config/sidebar.mjs`. Edit that file,
not `astro.config.mjs`.

`astro.config.mjs` composes the final sidebar from these groups plus the API
reference entries, the changelog link, and the private-docs link when sign-in
is configured. So if you are looking for the Changelog entry or an API
reference group, they are added there, not here.

```js
export const docsSidebarGroups = [
	{
		label: 'Get started',
		items: [
			{ label: 'Introduction', slug: 'get-started/introduction' },
			{ label: 'Quickstart', slug: 'get-started/quickstart' },
			/* ...Authentication */
		],
	},
	/* ...Guides, Concepts */
	{
		label: 'Reference',
		items: [{ autogenerate: { directory: 'reference' } }],
	},
];
```

## Linking to a page

`{ label, slug }` points at a page in the `docs` collection — the `slug` is
the page's file path under `src/content/docs/`, without the extension
(`get-started/quickstart` is `src/content/docs/get-started/quickstart.mdx`).

**Starlight fails the build** if a `slug` doesn't match a real page, so a
typo here is caught immediately rather than shipping a dead link.

For an external URL, or an in-site path that isn't a `docs` page, use
`{ label, link }` instead:

```js
{ label: 'Status page', link: 'https://status.example.com' }
```

## Grouping

`items` can nest another `{ label, items }` group to build a sub-menu. See
Starlight's [sidebar guide](https://starlight.astro.build/guides/sidebar/)
for nested groups, `collapsed`, and badges.

## Autogenerating a section

```js
{ label: 'Reference', items: [{ autogenerate: { directory: 'reference' } }] }
```

Every Markdown/MDX file under `src/content/docs/reference/` gets a sidebar
entry automatically, labeled from that page's `title` frontmatter and sorted
alphabetically by slug. Subdirectories become nested groups. Drop a new file
into that folder and it
appears in the sidebar with nothing to edit here — the reason the shipped
`reference/` section is set up this way.

## If you add a page and don't list it anywhere

The page still builds and is reachable at its URL. It just doesn't appear in
the sidebar until you add a `{ label, slug }` entry for it (or it lands
inside an autogenerated directory).

## Changing how one page shows up

**In an autogenerated directory,** the page's own frontmatter controls its
label, sort position and visibility:

```yaml
---
title: Send your first request
sidebar:
  label: First request # shorter than the page title
  order: 2             # lower numbers sort higher
  hidden: true         # drop it from the nav, keep the route
---
```

**In a hand-listed group,** edit the entry in `src/config/sidebar.mjs`
instead. `label`, `order` and `hidden` in frontmatter do nothing there — the
label comes from the config entry, the order is the order you wrote them in,
and removing a page from the nav means deleting its line.

A `badge` works either way.

:::note
This trips people up because the frontmatter is accepted without complaint in
both cases — it just has no effect in the second. If a `label` or `hidden`
seems to be ignored, check whether that page is listed by hand.
:::

Full field list in Starlight's
[frontmatter reference](https://starlight.astro.build/reference/frontmatter/#sidebar).