> ## Documentation Index
> Fetch the complete documentation index at: https://docs.olonjs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OlonJS menu.json reference: header and footer nav setup

> Configure your site's header and footer navigation in menu.json — add links, set labels, and designate a CTA button for the header bar.

OlonJS navigation menus are defined in `src/data/config/menu.json`. The file exports two menu arrays — `main` (used by the header navigation) and `footer` (used by the footer navigation) — each containing an ordered list of link objects. Reorder, add, or remove items here and the change propagates to every page automatically.

***

## menu.json structure

The file is a single JSON object with two top-level arrays:

```json src/data/config/menu.json theme={null}
{
  "main": [
    {
      "id": "menu-home",
      "label": "Home",
      "href": "/"
    },
    {
      "id": "menu-posts",
      "label": "Posts",
      "href": "/posts"
    },
    {
      "id": "menu-tags",
      "label": "Topics",
      "href": "/tags"
    },
    {
      "id": "menu-about",
      "label": "About",
      "href": "/about"
    },
    {
      "id": "menu-contact",
      "label": "Contact",
      "href": "/contact",
      "isCta": true
    }
  ],
  "footer": [
    {
      "id": "footer-posts",
      "label": "Posts",
      "href": "/posts"
    },
    {
      "id": "footer-tags",
      "label": "Topics",
      "href": "/tags"
    },
    {
      "id": "footer-about",
      "label": "About",
      "href": "/about"
    },
    {
      "id": "footer-contact",
      "label": "Contact",
      "href": "/contact"
    }
  ]
}
```

The `main` array drives the header navigation bar. The `footer` array drives the link row in the global footer. Both arrays are independent — you can include different items, in a different order, in each one.

***

## Menu item fields

Each object in a menu array accepts the following fields:

<ParamField body="id" type="string" required>
  A unique identifier for the menu item. Used internally by OlonJS to key list renders and resolve references. Use a short, kebab-cased string without spaces.

  ```json theme={null}
  "id": "menu-about"
  ```
</ParamField>

<ParamField body="label" type="string" required>
  The display text rendered in the navigation. Keep labels short — one or two words work best in horizontal header nav.

  ```json theme={null}
  "label": "About"
  ```
</ParamField>

<ParamField body="href" type="string" required>
  The destination URL for the link. Use a root-relative path (e.g. `/about`) for internal pages, or a full absolute URL (e.g. `https://github.com/your-org`) for external links.

  ```json theme={null}
  "href": "/about"
  ```
</ParamField>

<ParamField body="isCta" type="boolean" default="false">
  When `true`, the header renders this item as a primary CTA button instead of a plain text link. Use it for your most important conversion action — typically a "Sign up", "Get started", or "Contact" link.

  ```json theme={null}
  "isCta": true
  ```
</ParamField>

<Tip>
  Only set `isCta: true` on **one item per menu**. The header is designed to accommodate a single CTA button; marking multiple items as CTAs will apply primary button styling to all of them and dilute the visual hierarchy.
</Tip>

***

## Referencing menus in site.json

The header and footer blocks in `src/data/config/site.json` reference menus using the JSON Reference (`$ref`) pattern:

```json theme={null}
"menu": {
  "$ref": "../config/menu.json#/main"
}
```

The `$ref` value is a relative file path followed by a JSON Pointer fragment (`#/main` or `#/footer`). At build time, OlonJS resolves the reference and inlines the matching array. This means you maintain menu data in one place — `menu.json` — and both `site.json` and any section that references a menu stay in sync automatically.

| Reference | Resolves to |
| - | - |
| `../config/menu.json#/main` | The `main` array — used in `header.data.menu` |
| `../config/menu.json#/footer` | The `footer` array — used in `footer.data.menu` |

***

## Adding a menu item

To add a new item to the header navigation, append an object to the `main` array. The example below adds a **Newsletter** link between "About" and "Contact":

<CodeGroup>
  ```json Before theme={null}
  {
    "main": [
      { "id": "menu-home",    "label": "Home",    "href": "/" },
      { "id": "menu-posts",   "label": "Posts",   "href": "/posts" },
      { "id": "menu-tags",    "label": "Topics",  "href": "/tags" },
      { "id": "menu-about",   "label": "About",   "href": "/about" },
      { "id": "menu-contact", "label": "Contact", "href": "/contact", "isCta": true }
    ]
  }
  ```

  ```json After theme={null}
  {
    "main": [
      { "id": "menu-home",       "label": "Home",       "href": "/" },
      { "id": "menu-posts",      "label": "Posts",      "href": "/posts" },
      { "id": "menu-tags",       "label": "Topics",     "href": "/tags" },
      { "id": "menu-about",      "label": "About",      "href": "/about" },
      { "id": "menu-newsletter", "label": "Newsletter", "href": "/newsletter" },
      { "id": "menu-contact",    "label": "Contact",    "href": "/contact", "isCta": true }
    ]
  }
  ```
</CodeGroup>

Save the file and restart your dev server (or trigger a build in production) to see the new item appear in the header.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.