# Menus

## Menus

**Files:** `src/config/menu.en.json`, `src/config/menu.fr.json`, `src/config/menu.ar.json` · **Skill level:** Beginner

Each language has one menu file with three lists: `headerPrimary` (the top menu, its dropdowns, and the Services mega menu), `footerSecondary` (the **Pages** column of the footer), and `footerPrivacy` (the **Legal** column). Change every file when you change a link, so the languages stay in step. [Navigation](../../features/navigation/) has more on how the menu behaves.

In the Tina edition, open **Menus** at `/admin/`, then the file for your language. In the Sanity edition, the menu is not a file: in the Studio, open Content, your language, then **Menus**, which holds **Header menu**, **Footer links**, and **Legal links**.

### Header Menu
The order of items in the file is the order on the page. There are three kinds of item:

**1. A plain link**

```json
{ "enable": true, "name": "Contact", "url": "/contact/" }
```

**2. A dropdown.** Set `"hasChildren": true` and list the links in `children`. A child that has its own `"hasChildren": true` becomes a group with its own links. On large screens a group opens in a flyout beside the list, like **Home** in the demo's **Pages** menu. A group has no link of its own, so put its page in its `children` too:

```json
{
  "enable": true,
  "name": "Company",
  "hasChildren": true,
  "children": [
    { "enable": true, "name": "About us", "url": "/about/" },
    { "enable": true, "name": "Careers", "url": "/careers/" }
  ]
}
```

**3. A mega menu**, like **Services**. Set `"hasMegaMenu": true` and list groups in `menus`. Each group has a `name`, shown as a small label, and `children` links. On large screens the links are text only: with two or more groups, the first is in large type and the others are compact lists. A `cta` block adds a card with a photo, an eyebrow, a title, a short description, a checklist (`items`), and a button; on screens 1320px and wider it shows as a pane on the right. A `bar` block adds an optional strip along the bottom of the panel:

```json
{
  "enable": true,
  "name": "Services",
  "hasMegaMenu": true,
  "menus": [
    {
      "enable": true,
      "name": "Solar & storage",
      "children": [
        {
          "enable": true,
          "name": "Residential solar",
          "icon": "House",
          "url": "/services/residential-solar/"
        }
      ]
    }
  ],
  "cta": { "enable": true, "image": "/images/photos/...", "title": "...", "description": "...", "button": { "enable": true, "label": "Get a free quote", "url": "/contact/" } },
  "bar": { "enable": false, "text": "Not sure which service you need?", "label": "Talk to an adviser", "url": "/contact/" }
}
```

| Field         | What it does                                                                                   |
| ------------- | ---------------------------------------------------------------------------------------------- |
| `enable`      | **Required.** `true` shows the item, `false` hides it, in the header and the footer. Nested blocks such as `cta`, `button`, and `badge` need it too |
| `name`        | The text shown                                                                                 |
| `url`         | Where it goes: `/pricing/` for your pages (the language prefix is added for you) or a full `https://` address |
| `hasChildren` | `true` for a dropdown or a group inside one                                                    |
| `hasMegaMenu` | `true` for a mega menu with `menus`, `cta`, and `bar`                                          |
| `icon`        | A [Lucide icon](https://lucide.dev/icons/) name in PascalCase, such as `"House"` or `"BatteryCharging"`. Shown beside mega menu links in the mobile menu only |
| `description` | A short line about a mega menu link. The menu doesn't show it; the shipped files keep it for reference |
| `badge`       | A small label after the name: `{ "enable": true, "label": "New", "color": "accent", "type": "text" }`. Supported on plain links, dropdown links, and mega menu links, but the demo uses none |
| `cta`         | The mega menu's photo card: `image`, `eyebrow`, `title`, `description`, `items` (a checklist, large screens only), and `button`. In the desktop panel it shows on screens 1320px and wider |
| `bar`         | The mega menu's bottom strip, large screens only: `text`, then a link (`label` and `url`), then your phone number from `[settings.contactInfo]`. Off in the demo (`"enable": false`) |

Ecozen doesn't sort menu items by `weight`: they show in file order. The `weight` values in the shipped files are kept for reference, so move an item in the file to move it on the page.

The structure of the menu file is the same for every header style: on large screens, items with `hasChildren` or `hasMegaMenu` open in the shared dropdown panel described in [Header](/ecozen/customization/header/#desktop-dropdowns-and-the-mega-menu).

<Aside type="caution">
  In the header and the footer, an item without `"enable": true` is hidden. Copy an existing
  item when you add one, so you don't forget it.
</Aside>

On small screens the same items appear in the mobile menu panel. There, dropdowns and their groups open as lists, and the mega menu opens as a list too: each group's `name` as a small label, its links with their icons in small boxes, and the `cta` card (photo, eyebrow, title, description, and button) at the end. The `cta` checklist and the `bar` show only on large screens.

<Aside type="note" title="Updating from an older version?">
  Older menu files had an `intro` block (eyebrow, title, description) in the
  Services mega menu, and a `description` on each group. The theme no longer
  reads them, so you can delete them from your menu files.
</Aside>

### The Demo Menus
The **Pages** header item exists to show off the demo. It links to every page template: the four homepages (in a **Home** group: "Residential solar", "Commercial solar", "Renewable energy", and "EV and batteries"), a sample project, post, and service, the other inner pages, and **Components**, the shortcode demo page at `/components/`.

Most sites hide it:

```json
{ "name": "Pages", "enable": false, "hasChildren": true, "children": [ ... ] }
```

Also check the mega menu's **Featured project** link and its `cta` photo: they point at demo content.

### Footer Menus
The footer uses three link lists. Which ones show, and whether **Legal** is a column or a row of links at the very bottom, depends on the footer layout (see [Footer](/ecozen/customization/footer/)):

| List         | Where it comes from                                                         |
| ------------ | --------------------------------------------------------------------------- |
| **Pages**    | `footerSecondary` in the menu file                                          |
| **Services** | Your first six services by `weight`, from `src/content/services/`. No menu entry needed |
| **Legal**    | `footerPrivacy` in the menu file                                            |

```json
"footerSecondary": [
  { "enable": true, "name": "About", "url": "/about/" },
  { "enable": true, "name": "Careers", "url": "/careers/" }
]
```

The column headings are `common.pages`, `common.services`, and `common.legal` in the i18n files.

Set `"enable": false` on a footer link to hide it, as in the header.

The **Cookie settings** link in `footerPrivacy` uses `"url": "#cookie-settings"`, which reopens the cookie preferences. Set it to `"enable": false` if you turn the cookie banner off.

### Do It With AI
```text
Update the menus in every src/config/menu.*.json file. Header: [Home, Services (mega menu
with my services: ...), About, Projects, Pricing, Contact]. Hide the "Pages"
menu. Footer: footerSecondary [LINKS], footerPrivacy [Privacy Policy, Terms of Use, Cookie
settings]. Use Lucide icon names in PascalCase, keep "enable": true on every visible header item,
and translate the names for each language.
```