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

# Metafields in Aqua

> Read and render metafields in your theme using the {owner}.metafields.{namespace}.{key} pattern

# Metafields in Aqua / Liquid

Every owner that supports metafields exposes a `metafields` drop on its
Aqua/Liquid object. Access follows the standard
`{owner}.metafields.{namespace}.{key}` pattern, so theme code that reads
metafields stays portable.

For the full data model (types, owners, validations, REST API), see
[Metafields Overview](/api-reference/metafields/overview).

## The basic pattern

```aqua theme={null}
{{ product.metafields.custom.badge }}                  {# scalar value, type-aware toString #}
{{ product.metafields.custom.warranty_years }}         {# 5 #}
{{ product.metafields.custom.warranty_years.value }}   {# 5 (decoded) #}
{{ product.metafields.custom.warranty_years.type }}    {# "number_integer" #}
{{ product.metafields.custom.does_not_exist }}         {# (empty, no error) #}
```

`{{ … }}` triggers `toString()` on the metafield drop, which renders
type-aware (see [render rules](#render-rules-per-type) below). `.value`
returns the **decoded** value (number, array, object, …). `.type` returns
the type string.

Missing namespaces and missing keys return an **empty drop** — `{{ … }}`
prints empty string, `{% if … %}` is falsy, **no exception is thrown**.
This makes it safe to reference fields that may not exist on every
resource.

## Owners

| Owner           | Drop                    |
| --------------- | ----------------------- |
| Account / store | `shop.metafields`       |
| Product         | `product.metafields`    |
| Variant         | `variant.metafields`    |
| Collection      | `collection.metafields` |
| Customer        | `customer.metafields`   |
| Order           | `order.metafields`      |
| Page            | `page.metafields`       |
| Blog            | `blog.metafields`       |
| Article         | `article.metafields`    |

## Render rules per type

`{{ metafield }}` (without `.value`) calls a type-aware toString:

| Type                                               | `{{ mf }}` renders                                | `{{ mf.value }}` returns                        |
| -------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------- |
| `single_line_text_field` / `multi_line_text_field` | string                                            | string                                          |
| `rich_text_field` (alias `rich_text`)              | **raw HTML, unescaped**                           | raw HTML string                                 |
| `number_integer`                                   | integer                                           | number                                          |
| `number_decimal`                                   | decimal                                           | number                                          |
| `boolean`                                          | `"true"` or `"false"`                             | bool                                            |
| `color`                                            | `"#RRGGBB"`                                       | string                                          |
| `date` / `date_time`                               | ISO string                                        | string                                          |
| `url`                                              | URL string                                        | string                                          |
| `weight` / `dimension` / `volume`                  | `"<value> <unit>"`                                | `{ unit, value }`                               |
| `money`                                            | `{amount, currency_code}` (use `\| money` filter) | object                                          |
| `rating`                                           | `{value, scale_min, scale_max}`                   | object                                          |
| `file_reference`                                   | URL string                                        | URL string                                      |
| `*_reference` (other)                              | id string                                         | id string (or resolved drop, if resolver wired) |
| `list.*`                                           | iterable array of value-drops                     | array                                           |
| `json` / `json_string`                             | stringified JSON                                  | parsed value                                    |

## Examples

### Text and numbers

```aqua theme={null}
{% if product.metafields.custom.badge %}
  <span class="badge">{{ product.metafields.custom.badge }}</span>
{% endif %}

<p>Warranty: {{ product.metafields.custom.warranty_years }} years</p>
```

### Rich text (HTML)

The `rich_text_field` type renders the stored HTML **unescaped** — perfect
for care instructions, warnings, formatted descriptions:

```aqua theme={null}
<div class="care">
  {{ product.metafields.custom.care_instructions }}
</div>
```

### Boolean conditionals

```aqua theme={null}
{% if product.metafields.custom.is_featured %}
  <div class="featured-banner">Featured product</div>
{% endif %}
```

### Lists

```aqua theme={null}
{% for tag in product.metafields.custom.tags %}
  <span class="tag">{{ tag }}</span>
{% endfor %}

{% for review in product.metafields.reviews.list %}
  <article>
    <strong>{{ review.author }}</strong>
    <p>{{ review.body }}</p>
  </article>
{% endfor %}
```

### Money

```aqua theme={null}
<p>Deposit: {{ product.metafields.custom.deposit | money }}</p>
```

### Measurements

```aqua theme={null}
<dl>
  <dt>Weight</dt>
  <dd>{{ product.metafields.specs.weight }}</dd>     {# "1.2 KILOGRAMS" #}
  <dt>Dimensions</dt>
  <dd>{{ product.metafields.specs.dimension }}</dd>  {# "30 CENTIMETERS" #}
</dl>
```

### Color

```aqua theme={null}
<style>
  .product-card {
    border-color: {{ product.metafields.custom.brand_color }};
  }
</style>
```

### Date

```aqua theme={null}
{% if product.metafields.events.launches_on %}
  <p>Launching {{ product.metafields.events.launches_on | date: "%B %d, %Y" }}</p>
{% endif %}
```

### Reference (file)

```aqua theme={null}
{% if product.metafields.custom.spec_sheet %}
  <a href="{{ product.metafields.custom.spec_sheet }}">Download spec sheet</a>
{% endif %}
```

### JSON

```aqua theme={null}
{% assign specs = product.metafields.custom.specifications.value %}
<dl>
  <dt>Width</dt><dd>{{ specs.dimensions.width }}cm</dd>
  <dt>Weight</dt><dd>{{ specs.weight }}</dd>
</dl>
```

## Defensive access

Use `{% if %}` to guard optional fields — missing keys are falsy:

```aqua theme={null}
{% if product.metafields.custom.warranty_years %}
  <p>Warranty: {{ product.metafields.custom.warranty_years }} years</p>
{% endif %}
```

Or fall back with `default`:

```aqua theme={null}
<p>Color: {{ product.metafields.custom.brand_color | default: "#000000" }}</p>
```

## Across owner types

Same access pattern, every owner:

```aqua theme={null}
{{ shop.metafields.legal.tos_url }}
{{ collection.metafields.layout.banner_color }}
{{ customer.metafields.loyalty.tier }}
{{ order.metafields.fulfilment.gift_message }}
{{ page.metafields.seo.canonical }}
{{ blog.metafields.brand.theme_color }}
{{ article.metafields.editorial.byline }}
{{ variant.metafields.specs.weight }}
```

## Performance

Metafields are bulk-loaded server-side alongside the parent resource —
one query loads the resource, one query loads all its metafields, and
both are cached together. There is **no per-field network round-trip
from Liquid**.

When a metafield is written via the REST API, the relevant caches are
invalidated automatically. The next render sees the new value within
\~1 second.

## See also

* [Metafields Overview](/api-reference/metafields/overview) — types, owners, REST API
* [Create / Upsert Metafield](/api-reference/metafields/create) — write from your app
* [Aqua Filters](/aqua/filters) — `money`, `date`, `default`, etc.
