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

# Configuring Site Identity, Header, and Footer

> Update your portfolio's global branding, navigation links, header, footer, and social profiles by editing src/data/config/site.json and menu.json.

Your portfolio's global identity — name, header logo, footer copy, social links, and navigation menus — is controlled by two JSON files in `src/data/config/`. Updating these files changes the branding and navigation across every page at once, so you only need to edit one place when your name, job title, or social handles change.

## Configuration Files at a Glance

<CardGroup cols={2}>
  <Card title="site.json" icon="id-card">
    Controls your name/title, header logo text, footer description, copyright line, and social link array.
  </Card>

  <Card title="menu.json" icon="bars">
    Controls the main navigation items and the footer link list, including which item renders as a CTA button.
  </Card>
</CardGroup>

***

## `src/data/config/site.json`

This file holds three top-level keys: `identity`, `header`, and `footer`. The `header` and `footer` keys are full section objects — they have their own `id`, `type`, `data`, and `settings` sub-keys that the renderer uses to assemble the global shell.

### `identity`

The `identity` object stores your name or site title — used in the document `<title>` tag and as a fallback wherever the site needs to refer to itself generically.

| Field   | Type     | Description                                        |
| ------- | -------- | -------------------------------------------------- |
| `title` | `string` | Your full name or site title, e.g. `"Andrew Linh"` |

```json theme={null}
"identity": {
  "title": "Andrew Linh"
}
```

### `header`

The `header` key is a section object. Its `data` sub-object configures the logo, and its `settings` sub-object controls sticky behaviour.

#### `header.data` fields

| Field           | Type     | Description                                                                                    |
| --------------- | -------- | ---------------------------------------------------------------------------------------------- |
| `logoText`      | `string` | Full text rendered beside the logo mark, e.g. your name                                        |
| `logoHighlight` | `string` | Abbreviated initials shown inside the logo mark (e.g. `"AL"` for Andrew Linh)                  |
| `menu`          | `object` | Reference to the main nav array in `menu.json` — use `{ "$ref": "../config/menu.json#/main" }` |

#### `header.settings` fields

| Field    | Type      | Description                                                              |
| -------- | --------- | ------------------------------------------------------------------------ |
| `sticky` | `boolean` | When `true`, the header stays fixed at the top of the viewport on scroll |

The `logoHighlight` field is the short identifier that appears in the coloured logo tile. Use two or three characters — typically your initials.

```json theme={null}
"header": {
  "id": "global-header",
  "type": "header",
  "data": {
    "logoText": "Andrew Linh",
    "logoHighlight": "AL",
    "menu": { "$ref": "../config/menu.json#/main" }
  },
  "settings": { "sticky": true }
}
```

<Tip>
  Set `sticky: true` to keep your name and navigation in view as readers scroll through long blog posts or case studies. Set it to `false` for a cleaner, more editorial feel.
</Tip>

### `footer`

The `footer` key is also a section object. Its `data` sub-object controls all footer content including brand text, description, copyright, navigation links, and social icons.

#### `footer.data` fields

| Field            | Type     | Description                                                                                        |
| ---------------- | -------- | -------------------------------------------------------------------------------------------------- |
| `brandText`      | `string` | Short brand name shown at the top of the footer                                                    |
| `brandHighlight` | `string` | Tagline or descriptor rendered alongside the brand name                                            |
| `description`    | `string` | One or two sentences describing what you do                                                        |
| `copyright`      | `string` | Copyright line, e.g. `"© 2026 Andrew Linh."`                                                       |
| `menu`           | `object` | Reference to the footer nav array in `menu.json` — use `{ "$ref": "../config/menu.json#/footer" }` |
| `social`         | `array`  | Array of social link objects (see below)                                                           |

#### Social Links

Each entry in the `social` array has four fields:

| Field   | Type     | Description                                                     |
| ------- | -------- | --------------------------------------------------------------- |
| `id`    | `string` | Unique identifier for the link                                  |
| `label` | `string` | Accessible label and visible link text                          |
| `href`  | `string` | Full URL to the profile or feed                                 |
| `icon`  | `string` | Icon identifier — supported values: `github`, `linkedin`, `rss` |

```json theme={null}
"footer": {
  "id": "global-footer",
  "type": "footer",
  "data": {
    "brandText": "Andrew Linh",
    "brandHighlight": "systems · writing",
    "description": "Systems architect and technical writer. Backend architectures, structured data infrastructure, developer tools, and AI-native systems.",
    "copyright": "© 2026 Andrew Linh.",
    "menu": { "$ref": "../config/menu.json#/footer" },
    "social": [
      {
        "id": "gh",
        "label": "GitHub",
        "href": "https://github.com/andrewlinh",
        "icon": "github"
      },
      {
        "id": "li",
        "label": "LinkedIn",
        "href": "https://linkedin.com/in/andrewlinh",
        "icon": "linkedin"
      },
      {
        "id": "rss",
        "label": "RSS",
        "href": "/blog/rss.xml",
        "icon": "rss"
      }
    ]
  },
  "settings": { "showLogo": true }
}
```

<Note>
  Only `github`, `linkedin`, and `rss` are supported icon values. Using any other string will render no icon. If you need additional social networks, add the icon to the icon registry in `src/components/icons/` before referencing it here.
</Note>

### Full `site.json` Example

```json theme={null}
{
  "identity": {
    "title": "Andrew Linh"
  },
  "header": {
    "id": "global-header",
    "type": "header",
    "data": {
      "logoText": "Andrew Linh",
      "logoHighlight": "AL",
      "menu": { "$ref": "../config/menu.json#/main" }
    },
    "settings": { "sticky": true }
  },
  "footer": {
    "id": "global-footer",
    "type": "footer",
    "data": {
      "brandText": "Andrew Linh",
      "brandHighlight": "systems · writing",
      "description": "Systems architect and technical writer. Backend architectures, structured data infrastructure, developer tools, and AI-native systems.",
      "copyright": "© 2026 Andrew Linh.",
      "menu": { "$ref": "../config/menu.json#/footer" },
      "social": [
        { "id": "gh",  "label": "GitHub",   "href": "https://github.com/andrewlinh",          "icon": "github"   },
        { "id": "li",  "label": "LinkedIn",  "href": "https://linkedin.com/in/andrewlinh",     "icon": "linkedin" },
        { "id": "rss", "label": "RSS",       "href": "/blog/rss.xml",                          "icon": "rss"      }
      ]
    },
    "settings": { "showLogo": true }
  }
}
```

***

## `src/data/config/menu.json`

This file defines two navigation menus: `main` (the top-bar navigation) and `footer` (the footer link row).

### `main`

The `main` array controls which links appear in the site header. Items render in the order they appear in the array.

| Field   | Type                   | Description                                                                  |
| ------- | ---------------------- | ---------------------------------------------------------------------------- |
| `id`    | `string`               | Unique identifier for the nav item                                           |
| `label` | `string`               | Visible link text                                                            |
| `href`  | `string`               | URL path or absolute URL                                                     |
| `isCta` | `boolean` *(optional)* | When `true`, the item renders as a styled CTA button instead of a plain link |

Use `isCta: true` on one item — typically a "Contact" link — to create a visual call-to-action in the nav bar.

```json theme={null}
"main": [
  { "id": "nav-about",   "label": "About",   "href": "/about"   },
  { "id": "nav-work",    "label": "Work",    "href": "/work"    },
  { "id": "nav-blog",    "label": "Blog",    "href": "/blog"    },
  { "id": "nav-contact", "label": "Contact", "href": "/contact", "isCta": true }
]
```

### `footer`

The `footer` array defines the link row in the site footer. It follows the same shape as a `main` item but `isCta` is not used here.

```json theme={null}
"footer": [
  { "id": "ft-work",    "label": "Work",    "href": "/work"         },
  { "id": "ft-blog",    "label": "Blog",    "href": "/blog"         },
  { "id": "ft-contact", "label": "Contact", "href": "/contact"      },
  { "id": "ft-rss",     "label": "RSS",     "href": "/blog/rss.xml" }
]
```

### Full `menu.json` Example

```json theme={null}
{
  "main": [
    { "id": "nav-about",   "label": "About",   "href": "/about"   },
    { "id": "nav-work",    "label": "Work",    "href": "/work"    },
    { "id": "nav-blog",    "label": "Blog",    "href": "/blog"    },
    { "id": "nav-contact", "label": "Contact", "href": "/contact", "isCta": true }
  ],
  "footer": [
    { "id": "ft-work",    "label": "Work",    "href": "/work"         },
    { "id": "ft-blog",    "label": "Blog",    "href": "/blog"         },
    { "id": "ft-contact", "label": "Contact", "href": "/contact"      },
    { "id": "ft-rss",     "label": "RSS",     "href": "/blog/rss.xml" }
  ]
}
```

***

## Applying Changes

<Steps>
  <Step title="Edit the config file(s)">
    Open `src/data/config/site.json` or `src/data/config/menu.json` in your editor and make your changes.
  </Step>

  <Step title="Rebuild the site">
    Run the build command to bake the updated config into `public/`:

    ```bash theme={null}
    npm run build
    ```

    To preview changes without a full production build, use the dev server:

    ```bash theme={null}
    npm run dev
    ```
  </Step>

  <Step title="Or use Studio with Save2Repo">
    If you are editing through the visual Studio at `/admin` and **Save2Repo** is active, saving any config change writes the JSON file and triggers an automatic bake. No manual build step is required.
  </Step>
</Steps>

<Warning>
  Config changes — especially to `menu.json` — affect every page simultaneously. Always preview your changes locally with `npm run dev` before pushing to production to confirm the navigation looks correct across all breakpoints.
</Warning>
