# Use metafields in Liquid

> Read and render metafields in a Shoplazza Theme with Liquid: the access syntax, how to output each metafield type, and how to handle missing values.

After a metafield is created, you can read and display its value in your theme with Liquid. This guide covers the access syntax, how to render each metafield type, and how to handle missing values.

For what metafields are and how they're structured, see [Overview](/docs/theme/theme-features/custom-data/metafields/overview). For the full list of types, see [Types](/docs/theme/theme-features/custom-data/metafields/type).

## Access a metafield

Access a metafield through its parent resource, namespace, and key:

```liquid
{{ resource.metafields.namespace.key }}
```

- **Parent resource** — the object the metafield is attached to. In Liquid you read metafields from objects that expose a `metafields` property, reached through the relevant page: [`product`](/docs/theme/references/liquid/objects/product) on a product page and [`collection`](/docs/theme/references/liquid/objects/collection) on a collection page. Whether an object exposes `metafields` is listed on that object's reference page.
- **Namespace** — a container that groups related metafields so their keys don't collide (for example, `custom`).
- **Key** — the metafield's own name (for example, `spec_text`).

This returns a [metafield object](/docs/theme/references/liquid/objects/metafield), not the stored value. To output the value, append `.value`.

For example, suppose a product has a `single_line_text_field` metafield named `spec_text` in the `custom` namespace, holding `100% cotton`:

```liquid title="Code"
{{ product.metafields.custom.spec_text.value }}
```

```html title="Output"
100% cotton
```

:::warning
Accessing a metafield always returns a metafield object, even when the metafield doesn't exist — the result is never `nil`. Test `.value` for presence, not the metafield itself. See [Handle missing values](#handle-missing-values).
:::

## Render each type

How you read `.value` depends on the metafield [type](/docs/theme/theme-features/custom-data/metafields/type). Each example below assumes the product has the named metafield in the `custom` namespace.

### Text, number, date, boolean, color, and URL

These scalar types return the value directly from `.value`. For example, the `spec_text` single-line text field above (`100% cotton`):

```liquid title="Code"
{{ product.metafields.custom.spec_text.value }}
```

```html title="Output"
100% cotton
```

The same pattern applies to `multi_line_text_field`, `number_integer`, `number_decimal`, `date`, `date_time`, `boolean`, `color`, and `url`.

### JSON

For a `json` metafield, `.value` is a parsed object. Access nested properties by name. Suppose `details_json` holds `{"foo": "bar"}`:

```liquid title="Code"
{{ product.metafields.custom.details_json.value.foo }}
```

```html title="Output"
bar
```

### Measurement (weight, volume, dimension)

These return a [measurement object](/docs/theme/references/liquid/objects/measurement). Read the number and unit separately. For a `weight` metafield `net_weight` holding 20 kilograms:

```liquid title="Code"
{{ product.metafields.custom.net_weight.value.value }} {{ product.metafields.custom.net_weight.value.unit }}
```

```html title="Output"
20 KILOGRAMS
```

### Rating

A `rating` metafield returns a [rating object](/docs/theme/references/liquid/objects/rating). For a `review_score` rated 4 on a scale that tops out at 10:

```liquid title="Code"
{{ product.metafields.custom.review_score.value.value }} / {{ product.metafields.custom.review_score.value.scale_max }}
```

```html title="Output"
4 / 10.0
```

### File (image)

A `file_reference` metafield holds the file under `value.image`. For a `spec_file` holding an image, output the image URL directly, or pass `value` to the [`img_url`](/docs/theme/references/liquid/filters/media#img_url) filter to resize it:

```liquid title="Code"
<img src="{{ product.metafields.custom.spec_file.value.image.src }}">

<img src="{{ product.metafields.custom.spec_file.value | img_url: '400x' }}">
```

## Handle missing values

Because accessing a metafield never returns `nil`, guard your output on `.value`:

```liquid title="Code"
{% if product.metafields.custom.spec_text.value != blank %}
  <p>Material: {{ product.metafields.custom.spec_text.value }}</p>
{% endif %}
```

## Render with metafield filters

Instead of reading `.value` and building the markup yourself, the [`metafield_tag` and `metafield_text`](/docs/theme/references/liquid/filters/metafield) filters output a metafield based on its type:

* `metafield_tag` wraps the value in an HTML element suited to the type, with a `metafield-<type>` class — ready to drop into the page.
* `metafield_text` returns the value as plain text, for when you need the raw string.

For the `spec_text` field above (`100% cotton`):

```liquid title="Code"
{{ product.metafields.custom.spec_text | metafield_tag }}
{{ product.metafields.custom.spec_text | metafield_text }}
```

```html title="Output"
<span class="metafield-single_line_text_field">100% cotton</span>
100% cotton
```

## Read metafields with JavaScript

Liquid resolves metafields while the page renders, and only for the objects that page already has. To read a metafield after the page has loaded, or to read one for an object the page does not carry, use the Ajax Metafields API instead. It takes object ids, so it can read the metafields of any product, collection or the shop, and of several objects in one request.

See the [Ajax Metafields API reference](/docs/theme/references/ajax-api/metafields).

## Next steps

- [Metafield object reference](/docs/theme/references/liquid/objects/metafield)
- [Metafield filters reference](/docs/theme/references/liquid/filters/metafield)
- [Metafield types](/docs/theme/theme-features/custom-data/metafields/type)
