# List the variants

> Repeat a block once per variant of a product with smootify-variant. Covers variant cards in a Collection list, what a card shows, one card per colour, and the variant's swatches.

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

`smootify-variant` repeats a block once per variant of a Shopify product. Use it to show each colour of a product as its own card in a Collection list, or to list every size of a product with its price and stock. Each copy shows one variant: its title, options, image, price and stock.

> [!NOTE]
> Your products must be synced to the **Products** collection, with the `cms:Shopify ID` field filled in.

## How it works

Add a Custom element with the tag `smootify-variant`, and give it the custom attribute `data-product-id` with the product’s Shopify ID. The element is the first variant and the template of the others: Smootify copies it once per variant, right after it. Inside a Collection item, Smootify copies the whole Collection item, so each product becomes one item per variant.

What Smootify needs:

- a `smootify-variant` element with `data-product-id`. Without it, the element does nothing.

What is up to you:

- everything inside it: which values a copy shows, the layout, the classes;
- where it sits: in a Collection list, or on any page, with the id bound to a CMS field or typed in.

A product that Shopify does not return, because it is unpublished or not sold in the visitor’s market, removes the block. On your `.webflow.io` address, a note on the block says why instead.

## 1. Variant cards in a Collection list

1. Add a Collection list and connect it to the **Products** collection.
2. In the Collection item, add a Custom element with the tag `smootify-variant`.
3. Give it the custom attribute `data-product-id`, and take its value from the **Shopify ID** field.
4. Design one card inside it.

```html
<!-- Collection list settings. Source: Products -->
<div class="w-dyn-list">
  <div class="w-dyn-items">
    <div class="w-dyn-item">
      <smootify-variant data-product-id="{Shopify ID}">
        <a href="{Current Product}" class="w-inline-block" variant="url"><img variant="image"><div variant="title">Variant</div></a>
        <smootify-price><div data-prop="price">$0.00</div></smootify-price>
        <div condition="out-of-stock">Sold out</div>
      </smootify-variant>
    </div>
  </div>
</div>
```

In the Link Block’s settings, link it to **Current Product**: the card links to the product before Smootify loads, then Smootify writes the address of the variant.

The Collection list’s filters and sort order apply to the products, before Smootify turns each one into its variants.

## 2. What a card shows

Inside `smootify-variant`, the `variant` attributes show the values of that copy’s variant, and the `product` attributes show the values of its product:

- **`variant="title"`**: the variant’s title, such as `Red / M`. It is removed on a product without variants.
- **`variant="option1-name"` and `variant="option1-value"`** (`option2`, `option3` for the other options): the option’s name and value. They are removed when the variant does not have that option. With `remove-parent` on the value, its parent is removed too: use it for a “Size: M” row.
- **`variant="url"`** on a link: the product page with this variant chosen. `product="url"` also opens this variant, and keeps the text you designed.
- **`variant="image"`**, **`variant="sku"`**, **`variant="stock"`** and the other [variant values](https://www.smootify.io/docs/reference/attributes/variant).
- **`product="title"`**, **`product="vendor"`**, **`product="specific-image"`** and the other [product values](https://www.smootify.io/docs/reference/attributes/product). The gallery and video values do nothing here.
- **`smootify-price`**: this variant’s price and compare-at price.
- **`variant="unit-price"`**: this variant’s price per unit, such as `€1.50/ 100 g`, set in Shopify as explained in [Price per unit](https://www.smootify.io/docs/build/product-page#3-price).
- **`variant-metafield`**: this variant’s metafields ([Metafields on the page](https://www.smootify.io/docs/build/metafields)). Product metafields are not read on a variant card.

```html
<div>
  <div><div variant="option2-name">Size</div><div variant="option2-value" remove-parent="">M</div></div>
  <div variant="swatch1"><div swatch="color"></div><img swatch="image"><div swatch="name">Colour</div></div>
</div>
```

**States.** Each copy gets a class for the state of its variant, which you can style as a combo class. Inside a copy, a condition shows an element only in that state:

| State of the copy's variant | Class on the copy | Condition inside the copy |
|---|---|---|
| can be bought | `is-available` | `in-stock` |
| cannot be bought | `is-not-available` | `out-of-stock` |
| on sale: a compare-at price above the price | `is-on-sale` | `on-sale` |
| 5 or fewer left (0 counts too), or exactly one | `low-stock`, and `last-in-stock` for the last one | `low-stock`, `last-in-stock` |

Elements with `skeleton` shimmer until their copy is filled.

## 3. One card per colour

A product with 3 colours and 4 sizes has 12 variants, so it gets 12 cards. `unique-by` keeps one card per value of one option: the first variant with that value. Its value is the option’s position, counting from 0, unlike `data-option` on the pickers: `unique-by="0"` for the first option, `"1"` for the second, `"2"` for the third.

For a product with the options Size (S, M) and Color (Blue, Red):

Example: a product with the options Size (S, M) and Color (Blue, Red), so four variants in this order: S / Blue, S / Red, M / Blue, M / Red.

| `smootify-variant` | Cards | Which ones |
|---|---|---|
| without `unique-by` | 4 | one per variant |
| `unique-by="0"` (the first option, Size) | 2 | S / Blue and M / Blue: the first variant of each size |
| `unique-by="1"` (the second option, Color) | 2 | S / Blue and S / Red: the first variant of each color |

## 4. Swatches on a card

`variant="swatch1"` (or `swatch2`, `swatch3`) holds the swatch of the variant’s value for the first option (or the second, the third). Inside it, as in the example above:

- `swatch="color"`: the colour, as the background;
- `swatch="image"`: the image, on an Image, or as the background of another element;
- `swatch="name"`: the value’s name;
- `swatch="description"`: the description from the option metaobject.

The holder is removed when the value has no swatch, and each part is removed when its data is missing. Swatches come from Shopify’s native swatches or the option metaobject, as in the pickers: see [Swatch colours and images](https://www.smootify.io/docs/build/swatches). The metaobject is found by `Top: Oak` or `Oak`, and its description shows next to a native swatch too.

## On the product page

To list the variants of the page’s product, such as a table of sizes with price and stock, bind `data-product-id` to the **Shopify ID** field, as on a card. Place `smootify-variant` outside `smootify-product`: inside it, the product’s own `variant` attributes follow the variant that the visitor picks, and would write over the copies.

A variant card has no add-to-cart form: `smootify-add-to-cart` needs a `smootify-product` around it. Link the card to the product page with `variant="url"` instead, where the variant is already chosen.

More in [`smootify-variant`](https://www.smootify.io/docs/reference/elements/smootify-variant).

## Coming from 1.x

- `variation="…"` is removed: use `variant` with the same values, `variation="swatch1"` included.
- 1.x could redirect to another page when the product was missing. 2.0 removes the block and never redirects.
- A copy gets `is-on-sale` only when the compare-at price is higher than the price.

## Before you publish

> [!STUCK]
> - **Nothing repeats.** `data-product-id` is empty, or not bound to the `cms:Shopify ID` field.
> - **There are too many cards.** Every variant gets a card. Add `unique-by` with the option's position, counting from 0.
> - **`unique-by` groups by the wrong option.** The count starts at 0: the first option is `unique-by="0"`.
> - **The swatch holder disappears.** The value has neither a native swatch nor an option metaobject named after it.
> - **The swatch description is missing.** The value has a native swatch, which replaces the metaobject on a variant card.
> - **Attributes named `variation` do nothing.** 2.0 reads only `variant`.
