# Site fields

> Data the whole site shares, like opening hours or a row of badges, kept once and looped over by any page: a change is one edit, and no page is rewritten.
>
> From the MightyBuilder documentation: https://docs.mightybuilder.ai/dynamic/site-fields

Some data belongs to the whole site rather than to any one page: the opening
hours the footer and the contact page both show, a row of trust badges, the
services a menu lists. **Site fields** keep that data once, on the site, and
any page reads it — so changing Saturday's hours is one edit, and no page has
to be rewritten to follow it.

## When to use them

Use site fields for data that is **a list a page loops over**, or **a value you
want to change yourself** without asking the AI. Most sites have none, and that
is fine.

They are not for everything:

- A sentence that appears in one place belongs in that page's own words.
- A fact the site repeats — a phone number in the footer — can simply be
  written once in the [block](/pages/blocks) every page shows.
- Anything with a page of its own — a team member, a product — is a
  [collection](/dynamic/collections).

The easiest way to get them is to ask: *"make our opening hours something I can
edit, and show them in the footer."*

## Defining them

Site fields are defined and filled in on one screen, **Settings › Fields**.
The top half is the fields written out as code, in exactly the format a
collection's fields use — so every type on [An item's fields](/dynamic/fields)
works here too, from `telephone` and `link` to `hours`, `image` and
`repeater`. The bottom half is the form those fields draw, one box per field,
saved as you type.

Changes are saved to the draft, like every other edit, and go live when you
publish.

## Reading them

A page reads them as `site.fields`, followed by the field's name:

```liquid
<p>Call us on {{ site.fields.phone }}</p>
```

A repeater is looped over, in the order its rows are in on the form:

```liquid
<ul class="hours">
  {% for h in site.fields.hours %}
    <li>{{ h.day }}: {{ h.open }}</li>
  {% endfor %}
</ul>
```

A single row can be named by its key — `{{ site.fields.hours.saturday.open }}`
— but never by its position, for the same reason as an item's rows: dragging
the rows into a different order would change what it points at.

```liquid-invalid
<p>{{ site.fields.hours[0].open }}</p>
```

The same guards apply as for an item. Anything that only makes sense when a
value exists goes inside a plain `{% if %}` on that value:

```liquid
{% if site.fields.phone %}
  <a href="tel:{{ site.fields.phone | tel }}">{{ site.fields.phone }}</a>
{% endif %}
```

A field of type **link** can fill an `href` on its own —
`<a href="{{ site.fields.booking }}">Book a table</a>` — exactly as on
[an item](/dynamic/fields#links).

They work in your site's structured data too, which is often the best place
for opening hours: search engines read them there.

## What is protected

**A field a page reads cannot be removed, renamed or given a different type**
until that page stops reading it. The same goes for a row a page names by its
key. Structured data counts as reading.

**Publishing checks the values under every page that reads them.** An empty
link that would fill a button stops the publish, an empty value printed on its
own is pointed out, and a loop in your structured data is tried with the rows
you really have. That holds even when the only thing you changed was a value.

## Going back

Site fields are part of the site's settings, so **Overview → Releases** keeps
them with every release. Putting them back restores the fields and what was filled in,
together. If an earlier version would leave a page reading a field it did not
have yet, the restore says which field and changes nothing.
