2.0 Beta

Smootify 2.0 is in public beta. Your 1.x store keeps working. Move when you want.

What changed

List the variants

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

v2.0 beta
Open .md
On this page
  1. How it works
  2. 1. Variant cards in a list
  3. 2. What a card shows
  4. 3. One card per colour
  5. 4. Swatches on a card
  6. On the product page
  7. Before you publish

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 list of products, 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 loaded as the products content collection, so that every entry has its shopifyId: see Content.

How it works

Write a smootify-variant element, and give it the 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 an element with the class sm-dyn-item, the boundary of a card, Smootify copies the whole sm-dyn-item, so each product becomes one card 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 list of entries, or on any page, with the id from the entry 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. In the dev server and on your *.workers.dev address, a note on the block says why instead.

1. Variant cards in a list

  1. In the page, map the entries of the products collection to cards.
  2. In each card, write a smootify-variant element, inside an element with the class sm-dyn-item.
  3. Set its data-product-id to the entry’s shopifyId.
  4. Write one card inside it.
---
import { getCollection } from "astro:content";
const products = await getCollection("products");
---
{products.map(({ id, data: p }) => (
  <div class="sm-dyn-item">
    <smootify-variant data-product-id={p.shopifyId}>
      <a href={`/products/${id}/`} variant="url"><img variant="image" src={p.image} alt={p.imageAlt} /><div variant="title"></div></a>
      <smootify-price><span data-prop="price">{p.priceFormatted}</span></smootify-price>
      <div condition="out-of-stock">Sold out</div>
    </smootify-variant>
  </div>
))}

Render the link to the product page, so the card links to the product before Smootify loads. Smootify then writes the address of the variant.

The entries you list, and their order, decide the products. Smootify then 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.
  • product="title", product="vendor", product="specific-image" and the other product values. 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.
  • variant-metafield: this variant’s metafields (Metafields on the page). Product metafields are not read on a variant card.
<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 in CSS. Inside a copy, a condition shows an element only in that state:

Can be bought

Class
is-available
Condition
in-stock

Cannot be bought

Class
is-not-available
Condition
out-of-stock

On sale

Class
is-on-sale
Condition
on-sale
When
A compare-at price above the price.

5 or fewer left

Class
low-stocklast-in-stock
Condition
low-stocklast-in-stock
When
low-stock at 5 or fewer, 0 counts too. last-in-stock at exactly one.

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):

no unique-by

Every variant

One card per variant.

unique-by="0"

One card per size

S / Blue and M / Blue: the first variant of each size, the first option.

unique-by="1"

One card per color

S / Blue and S / Red: the first variant of each color, the second option.

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 <img>, 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. 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, set data-product-id to the entry’s shopifyId, 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.

Before you publish

Check these first

  • Nothing repeats. data-product-id is empty: it is not set to the entry’s shopifyId.
  • 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.

    ↑ ↓ to moveEnter to openEsc to close