# Swatch colours and images

> Where the colour and image of a swatch come from, Shopify's native swatches and the option metaobject, how to set each one up in Shopify, and how to show swatches in pickers and on product cards.

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

A swatch is the colour or the picture that stands for an option value: a red dot for Red, a wood sample for Oak. Smootify takes swatches from Shopify, so there is nothing to upload in Webflow. This page explains the two places a swatch comes from, how to set each one up in Shopify, and how to show swatches in the pickers and on product cards.

> [!NOTE]
> You need a picker on the product page, as in [Build the product page](https://www.smootify.io/docs/build/product-page). To set up the option metaobject, you need access to **Settings › Custom data** in the Shopify admin.

## Where a swatch comes from

For each option value, Smootify looks in two places:

1. **Shopify’s native swatch.** When an option is created from a category metafield, such as Color, each of its values has a colour or an image. You set it once in Shopify, and every product that uses the value shares it.
2. **The option metaobject.** A metaobject named after the value, selected in the product metafield `custom.options`. It has a colour, an image, a description, and any other field you add.

The native swatch wins, but only for the colour and the image. The description and the other fields always come from the metaobject. So you can use both: Shopify’s colour, plus a metaobject for a description or a delivery note.

Smootify does not look anywhere else. A value with neither source has no colour and no image.

## Shopify’s native swatches

1. In Shopify, set the product’s **category**.
2. Add the option by choosing the category metafield, for example **Color**, and pick its values. Each value has its colour or image in Shopify.

**Link the option when you create it.** An option created first and linked to the Color metafield afterwards keeps empty swatches: Shopify does not fill them. Delete the option and add it again, starting from the Color metafield. This creates the variants again, so note their SKUs, prices and stock first.

## The option metaobject

Use it for values that have no native swatch, or to add a description or other data to each value.

Here is the whole set-up as it looks in the Shopify admin, for a table sold in oak, walnut and white:

In the Shopify admin: 1. Settings › Custom data › Metaobjects: the Option definition with the fields name (single line text), color (color), image (file) and description (multi-line text), Storefronts access on. 2. Content › Metaobjects › Option: one entry per value, its name written as the value (Oak, Walnut, White). 3. On each product, the Options metafield (custom.options, Metaobject Option, list) selects the entries of its values.

1. In Shopify, go to **Settings › Custom data**, open **Metaobjects** and add a definition named **Option**. Give it four fields with these keys: `name` (single line text), `color` (color), `image` (file) and `description` (multi-line text). Add any other field you need.
2. Back in **Settings › Custom data**, open **Products** and add a metafield definition with the namespace and key `custom.options`. Its type is **Metaobject**, it references **Option**, and it holds a list of entries.
3. Turn on **Storefront access** on both definitions.
4. Create one **Option** entry per value. On each product, select the entries of its values in the **Options** metafield.

**The name must match the value.** Write the entry’s `name` exactly as the value is written in Shopify: `Oak`. When the same value exists in two options and must look different in each, write the option’s name, a colon and a space first: `Top: Oak`, `Legs: Oak`.

## Show the swatch in a picker

Three of the four pickers show every part of a swatch. `variant-selector` is the browser’s own select, so it holds text only:

| Swatch part | Written as | `variant-swatches` | `variant-dropdown` | `variant-popover` | `variant-selector` |
|---|---|---|---|---|---|
| Color and image | `option="bg-color"`, `"image"` | yes | yes | yes | no |
| Name | `option="title"` | yes | yes | yes | yes, written by Smootify |
| Description | `option="description"` | yes | yes | yes | no |
| Other metaobject fields | `option-metafield="key"` | yes | yes | yes | no |
| Variant photo | `option-variant="image"` | yes | yes | yes | no |
| Price or difference | `smootify-price`, `option="price-difference"` | yes | yes | yes | in the text, with `data-format="{{value}} {{difference}}"` |

Put these attributes inside the value template: the first button of `variant-swatches`, the first link of `variant-dropdown`, the first link or button of `variant-popover`. Every value is a copy of the template, so every attribute goes on it or inside it.

- `option="bg-color"`: the colour, as the element’s background, for a colour dot;
- `option="color"`: the colour, as the text colour;
- `option="image"`: the image, on an Image, or as the background of any other element;
- `option="description"`: the metaobject’s description, removed when there is none;
- `option-metafield="lead_time"`: any other field of the metaobject, by its key. On a value without a metaobject it is hidden, and a field that references a product or a collection links to its page on your site;
- `option="title"`: the value’s name.

```html
<variant-swatches data-option-name="Color,Colour">
  <button><img option="image"><span option="title">Value</span><span option="description">Description</span><span option-metafield="lead_time">Ships in 3 weeks</span></button>
</variant-swatches>
```

When a value has no image, the Image with `option="image"` is removed if the value has a native swatch or a metaobject, so a colour-only value shows no empty image. If the value has neither, the Image is hidden.

A `variant-swatches` button that shows only a colour or an image, with no text, gets the value’s name as its label for screen readers.

Two more parts work inside the template:

- `option-variant="image"`: the product photo of the variant that the value leads to, with the other options as chosen;
- `smootify-price` and `option="price-difference"`: the value’s price, or what it adds to the price, as in [Build the product page](https://www.smootify.io/docs/build/product-page).

On `variant-selector`, `data-format="{{value}} {{difference}}"` on the Select field writes the difference into each option’s text, such as “Walnut + €180”. The cheapest value shows its name only.

**Show the chosen value.** Inside the picker, outside the button, `selected-option="bg-color"`, `"color"`, `"image"` or `"title"` shows the swatch or name of the chosen value, for a label such as “Colour: Red” with a dot.

Every value: [option values](https://www.smootify.io/docs/reference/attributes/option), [option metafields](https://www.smootify.io/docs/reference/attributes/option-metafield) and [chosen value](https://www.smootify.io/docs/reference/attributes/selected-option).

## Option values on product cards

`product="option-values"` shows every value of one option, one copy of the element each: the colour dots of a product card. Put it inside the card’s `smootify-product`.

- Choose the option with `data-option-name="Color,Colour"` (the first of these names that the product has) or `data-option="2"` (counting from 1). Without either, it shows the first option.
- Inside each copy, the same `option` and `option-metafield` attributes work as in a picker, also on the copy itself.
- A copy without any of them shows the value’s name.
- A product without that option, or without options, loses the element.

The dots only show the values: a click does not choose a variant, and `option="price-difference"` stays hidden here. To open the product with a value already chosen, put a link with `product="link"` inside the copy: it goes to the product page with the first available variant of that value, such as a “Join the waitlist” link next to a wood that comes in the next batch. Other links in the copy keep the address you gave them.

```html
<div product="option-values" data-option-name="Color,Colour"><div option="bg-color"></div></div>
```

More on cards in [Product cards](https://www.smootify.io/docs/build/product-cards).

## Other elements called swatches

The word covers other elements too, and they read swatches in their own way:

- **Variant cards**: `variant="swatch1"` with `swatch` parts inside `smootify-variant`. They read the native swatch and the option metaobject as a picker does. See [List the variants](https://www.smootify.io/docs/build/variants-list).
- **Filter swatches**: `filter-swatches` shows only Shopify’s native swatch, as Shopify’s Search & Discovery app sends it. Option metaobjects do not reach it. See [Filters, sorting and pagination](https://www.smootify.io/docs/build/filters).
- **Add-on swatches**: `addon-swatches` uses the same two sources as a picker when the add-on has one option. See [Product add-ons](https://www.smootify.io/docs/features/add-ons).
- **Subscription swatches** choose a selling plan and have no colours: see [Subscriptions](https://www.smootify.io/docs/features/subscriptions). **Dynamic property swatches** take their choices from the property: see [Dynamic properties](https://www.smootify.io/docs/features/dynamic-properties).

## Coming from 1.x

1.x also looked up every colour pattern of the shop by the value’s name. 2.0 reads only the value’s native swatch and its option metaobject. If colours are missing after the move, the option was probably linked to the Color metafield after it was created: see Shopify’s native swatches, above.

Inside a swatch button, 2.0 no longer fills `variant="image"`: use `option-variant="image"`.

## Before you publish

> [!STUCK]
> - **The swatches of a Color option have no colour.** The option was linked to the Color metafield after it was created. Delete it and add it again from the metafield, after noting SKUs, prices and stock.
> - **The metaobject's colour is ignored.** The value has a native swatch, and its colour and image win. The description and the other fields still come from the metaobject.
> - **Nothing comes from the metaobject.** Check that the entry's `name` matches the value exactly, that the field keys are `name`, `color`, `image` and `description`, that the entry is selected in the product's `custom.options`, and that both definitions have Storefront access.
> - **The dot has no colour, but the text does.** `option="color"` colours the text. Use `option="bg-color"` for a dot.
> - **The variant photo in a swatch stays empty.** Use `option-variant="image"`: `variant="image"` does nothing inside a swatch button.
> - **Attributes on a swatch do nothing.** They are on the second button or link: only the first one is the template. In `variant-selector`, swatch attributes never work: use one of the other pickers.
