# Metafields on the page

> Show the Shopify metafields of a product and its variants. Covers what each type shows, lists, values written into attributes, colours, JSON, references, ratings, and elements shown or hidden by a metafield.

Status: Ready (Smootify 2.0)  
1.x page: https://docs.smootify.io/docs/ecommerce/products/metafields  
URL: https://www.smootify.io/docs/build/metafields  
Updated: 2026-10-10

Metafields hold the extra data of a Shopify product or variant: a material, a care guide, a spec sheet, a list of ingredients. Smootify shows them on the page straight from Shopify, without copying them to the Webflow CMS. [Build the product page](https://www.smootify.io/docs/build/product-page) shows the basic attribute. This page covers the rest: what each type shows, lists, values in attributes, JSON, references, ratings and conditions.

> [!NOTE]
> In Shopify, each metafield needs a definition (**Settings › Custom data**) with **Storefront access** turned on. For a reference to a metaobject, the metaobject's definition needs Storefront access too.

## Show a metafield

`metafield="material"` on an element inside `smootify-product` shows the product metafield `custom.material`. Here is the whole path, from the Shopify admin to the page:

In the Shopify admin: 1. Settings › Custom data › Products: a definition named Material, namespace and key custom.material, type Single line text, Storefronts access on. 2. On a product, its Metafields card holds the value: Material = Linen; a review app writes Rating in its own namespace, reviews.rating = 4.5 out of 5. 3. In Webflow, inside smootify-product: `metafield="material"` shows Linen; `metafield="rating" namespace="reviews"` shows 4.5 and sets `--metafield-rating` to 90%.

- **Namespace.** Smootify reads the namespace `custom` unless you add `namespace="…"`, for example `namespace="reviews"` for `reviews.rating`.
- **Variant metafields.** `variant-metafield="…"` shows a metafield of the selected variant, and changes with it, a video included.
- **Where they work.** `metafield` works inside `smootify-product`, on the product page and on product cards, and inside a cart line, where it reads the line’s product ([Build the cart](https://www.smootify.io/docs/build/cart)). `variant-metafield` works inside `smootify-product` and on variant cards ([List the variants](https://www.smootify.io/docs/build/variants-list)). Anywhere else, Smootify does not read the attribute.
- **Empty values.** When the metafield is empty or missing, the element is hidden. What you type in the Designer stays as a placeholder until the value arrives. With `data-fallback="…"`, the element stays and shows that text instead. An empty `data-fallback` is ignored, so a component can bind it to a text property that most instances leave empty.

### What each type shows

| Metafield type | Put it on | What it shows |
|---|---|---|
| Text, number, date | a Text block or a Heading | the value; multi-line text keeps its line breaks |
| Rich text | a Rich text element | the text with its formatting |
| Money | a Text block | the amount, formatted as a price |
| Weight, volume, dimension | a Text block | the value with its unit, such as `650 g` |
| True or false | any element | the element, only when true |
| File: image | an Image | the image |
| File: other | a Text link or Link block | a link to the file |
| File: video | a Div block | a video that plays muted, on a loop |
| URL, link | a Text link or Link block | the link; a link type also sets the text |
| Color, rating | any element | a CSS variable: see below |

Every type, list types included: [metafield types](https://www.smootify.io/docs/reference/metafield-types).

## Lists

A list of text, numbers, dates or measures is joined into one text, such as `Cotton, Linen`. Two ways to change that:

- `separator=" / "` joins the values with the text you write, spaces included. The default is a comma and a space.
- `separator="repeat"` makes one copy of the element per value. Design one item, and lay out the list as you like.

```html
<div>
  <div metafield="ingredients" separator="repeat">Ingredient</div>
</div>
```

Lists of files, colours, URLs, links, ratings, references and metaobjects always make one copy of the element per item.

## Values in attributes, decimals and colours

- **`data-attr="aria-label"`** writes the value into that attribute instead of the element’s content. It works for text, whole numbers, ratings and values from JSON. Use it for a label that screen readers read, a `title`, or an image’s `alt`.
- **`data-digits="1"`** rounds a decimal number, and the text of a rating, to that many decimals.
- **Colours.** A colour metafield writes no text. It sets the CSS variable `--metafield-color` on the element, and `property="--badge-color"` gives the variable another name. Use the variable in your styles, for example as a background colour, so the merchant can change a badge colour in Shopify. A list of colours makes one copy of the element per colour, each with its own variable.

## JSON

A JSON metafield shows nothing until `data-path` points at a value:

- `data-path="size.width"` shows one value. Separate the keys with dots.
- `data-path="colors.0"` shows the first item of a list. Positions count from 0.
- A path that is not in the JSON hides the element.

```html
<div>
  <div metafield="specs" data-path="size.width">0</div>
  <div metafield="specs" data-path="colors.0">Colour</div>
</div>
```

For several values of one metafield, you can also put `data-path` on elements inside a single `metafield` element, each with its own path. A path that leads to a list of objects repeats its element once per object, and the paths inside each copy start from that object. This makes a table of specs from JSON such as `[{"label": "Height", "value": "90 cm"}]`.

Without any `data-path`, a JSON metafield is left to custom code: see [Render a metafield yourself](https://www.smootify.io/docs/developers/custom-metafields).

## References

A metafield that references a product, a variant, a collection or a page shows it according to the element:

- on a Text link or Link block, it links to it (a variant link opens the product page on that variant);
- on an Image, it shows its image;
- on an element without children, it shows its title.

Inside the element, `reference="title"`, `"url"`, `"image"`, `"handle"`, `"description"` (collections) and `"body"` (pages) show those parts. A part that the reference does not have is hidden. Pages have no URL on a Webflow site. A list of references repeats the element once per reference.

```html
<a href="#" class="w-inline-block" metafield="pairs_with">
  <img reference="image">
  <div reference="title">Product</div>
</a>
```

For product cards with a price and an add-to-cart button, use a `smootify-product` whose `data-id` names the metafield instead: see [Product lists without the CMS](https://www.smootify.io/docs/build/product-lists).

**Metaobjects.** Inside an element with a metaobject reference, `metaobject="field"` shows a field of the metaobject. A list repeats the element once per metaobject. On a link inside it, `metaobject-url="/materials/{handle}"` builds the link from the metaobject’s handle. More in [Show metaobjects](https://www.smootify.io/docs/features/metaobjects).

## Ratings

A rating metafield, such as `reviews.rating` from a review app:

- on an element without children, shows the value as text, such as `4.5`;
- always sets the CSS variable `--metafield-rating` on the element: the rating as a share of its scale, such as `90%` for 4.5 out of 5.

An element with children keeps them and only gets the variable. For stars, put a fill inside it that holds the row of stars, with its overflow hidden and a width of `var(--metafield-rating)`: it covers that share of the row. `data-attr="aria-label"` gives the value to screen readers.

```html
<div metafield="rating" namespace="reviews" data-attr="aria-label">
  <div>★★★★★</div>
</div>
```

The review apps that write this metafield: [Product reviews](https://www.smootify.io/docs/features/reviews).

## Show or hide by a metafield

`if-metafield="key"` shows an element only when the metafield says so, and `unless-metafield="key"` hides it. Both take `namespace`, and have a variant version: `if-variant-metafield` and `unless-variant-metafield`. For example, `if-metafield="vegan"` on a badge shows it only on products whose `custom.vegan` is true.

| The metafield is | `if-metafield` shows the element when | `unless-metafield` hides it when |
|---|---|---|
| true or false | it is true | it is true |
| a number | it is above 0 | it has a value |
| checked with `data-check-value="Oak"` | it is `Oak` (a list: contains `Oak`) | it is `Oak` (a list: contains `Oak`) |
| any other type | it has a value | it has a value |

Every condition: [product metafield conditions](https://www.smootify.io/docs/reference/conditions/product-metafield) and [variant metafield conditions](https://www.smootify.io/docs/reference/conditions/variant-metafield).

## Coming from 1.x

- The types 1.x left to custom code now render: lists of numbers, dates, measures, colours, URLs and ratings, ratings, JSON with `data-path`, and references. A script listening to `smootify.devMetafield` still runs, after Smootify’s render: see [Render a metafield yourself](https://www.smootify.io/docs/developers/custom-metafields).
- Weight and volume show the unit symbol, `650 g` (1.x showed `650 GRAMS`). Dates show the day saved in Shopify in every time zone.
- `separator` keeps the spaces you write: `separator=", "` is a comma and a space (1.x trimmed it to a comma).

## Before you publish

> [!STUCK]
> - **A metafield stays empty.** Its definition in Shopify needs Storefront access. For a metaobject reference, the metaobject's definition needs it too.
> - **Still empty with Storefront access.** The namespace is not `custom`: add `namespace="…"`.
> - **The element keeps its placeholder text.** It is outside `smootify-product`, a variant card or a cart line, where Smootify does not read metafields.
> - **A list shows as one line.** Add `separator="repeat"` to get one element per value.
> - **A JSON metafield shows nothing.** Add `data-path` with the key of the value.
> - **The stars do not fill.** The fill must be inside the element with the rating metafield, with a width of `var(--metafield-rating)`.
