> ## 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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.