# Customizing Menus

## Customizing Menus In Techlo

**Files:** `src/config/menu.<lang>.json` · **Skill level:** Beginner

Techlo has one menu file for each language: `src/config/menu.en.json`, `menu.fr.json`, and `menu.ar.json`. Each file has two lists:

- `headerPrimary`: the header menu, with dropdowns and mega menus
- `footer`: the footer link columns

In the Tina edition, you edit these under **Menus** at `/admin/`, per language: **Header Primary** and **Footer**. In the Sanity edition, the file doesn't exist: open Content, your language, **Menus** in the Studio, then **Header menu** or **Footer menu**.

For how the menu behaves, and for keyboard support, see [Navigation](../../features/navigation/).

<Aside type="caution">
  Change the menu file of **every language** when you add or remove a link, so
  the menus stay in step.
</Aside>

---

### Header Menu Items
Each object in `headerPrimary` is a top-level menu item. It can be a plain link, a dropdown, or a mega menu.

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

- `name`: text displayed in the header
- `url`: link destination. Use `/pricing/` for your own pages, and the language prefix is added for you
- `enable`: `true` shows the item. An item with `false`, or with no `enable` at all, is hidden
- `weight`: a number kept with each item
- `hasChildren`: makes the item a dropdown
- `children`: the links inside a dropdown
- `hasMegaMenu`: makes the item a mega menu
- `badge`: a small label or dot beside the name

### Techlo Shows Items In File Order
Techlo doesn't sort the menu by `weight`. Items appear in the order they have in the file, at every level. To move an item, move it in the file, or in the list in your editor. Changing `weight`, or **Order** in the Tina form, doesn't move it.

---

### Dropdowns And Nested Menus
Give an item `"hasChildren": true` and a `children` list. Any child can have its own `hasChildren` and `children`, and it opens to the side. **Pages > Projects > Single** in the sample menu is an example.

```json
{
  "enable": true,
  "name": "Pages",
  "weight": 2,
  "hasChildren": true,
  "children": [
    { "enable": true, "name": "About", "weight": 1, "url": "/about/" },
    {
      "enable": true,
      "name": "Services",
      "weight": 2,
      "hasChildren": true,
      "children": [
        { "enable": true, "name": "List", "weight": 0, "url": "/services/" },
        { "enable": true, "name": "Single", "weight": 1, "url": "/services/service-custom-slug/" }
      ]
    }
  ]
}
```

You can nest as deep as you like in the file and in the Sanity edition. The Tina form reaches at least four levels. After you add a deeper level in the file, run `npm run tina:generate` and the form follows it.

### Mega Menus
Set `"hasMegaMenu": true` and list groups of links in `menus`, as in the **Services** item of the sample menu. `cta` adds the photo card, and `bar` adds the row along the bottom.

```json
{
  "enable": true,
  "name": "Services",
  "weight": 1,
  "hasMegaMenu": true,
  "menus": [
    {
      "enable": true,
      "name": "Build & Design",
      "weight": 0,
      "children": [
        {
          "enable": true,
          "name": "Web & Mobile App Development",
          "weight": 0,
          "description": "Design and develop responsive web and mobile apps.",
          "icon": "Smartphone",
          "url": "/services/service-02/"
        }
      ]
    }
  ],
  "cta": {
    "enable": true,
    "eyebrow": "Work with us",
    "image": "/images/services/it-management.jpg",
    "title": "Not sure which service fits?",
    "description": "One short sentence.",
    "button": { "enable": true, "label": "Get in Touch", "url": "/contact/" }
  },
  "bar": {
    "enable": true,
    "text": "Explore everything we offer.",
    "label": "View all services",
    "url": "/services/"
  }
}
```

### Badges
A header item can have a small badge:

```json
{
  "enable": true,
  "name": "Components",
  "weight": 3,
  "url": "/components/",
  "badge": {
    "enable": true,
    "label": "NEW",
    "color": "accent",
    "type": "text"
  }
}
```

`color` can be `primary`, `accent`, `info`, `warning`, `success`, or `danger`. `type` is `text`, or `dot` for a dot with no label.

---

### Footer Menus
Techlo’s footer columns are in the `footer` list. Each object is one column, with a `label` for its heading and a `list` of links. The sample columns are **Quick Links**, **Services**, and **Company**.

```json
{
  "footer": [
    {
      "label": "Quick Links",
      "list": [
        { "enable": true, "name": "About Us", "url": "/about/" },
        { "enable": true, "name": "Contact Us", "url": "/contact/" }
      ]
    }
  ]
}
```

Footer links have `enable`, `name`, and `url`, and an optional `active` that highlights the link. A footer link is hidden only when `enable` is `false`.

### Adding And Hiding Menu Items
1. Open `src/config/menu.en.json`, then the same file for each of your other languages.
2. Find the list you want to change: `headerPrimary` or `footer`.
3. Add a new object where you want it to appear, with `enable`, `name`, and `url`.

To hide an item without deleting it, set `enable` to `false`:

```json
{
  "enable": false,
  "name": "Old Page",
  "url": "/old-page/"
}
```

### Do It With AI
```text
Add a link called "[NAME]" to [/PAGE/] in the [HEADER MENU / FOOTER COLUMN NAME]. Edit
src/config/menu.en.json, menu.fr.json, and menu.ar.json, and translate the name for each language.
Items show in file order, so put it where I want it: [POSITION]. Keep the same item shape as the
items around it, and don't change the navigation components. Then run npm run astro-check.
```