Variants

Sell a product in colors and sizes, each variant with its own price and stock, and show the one the shopper filtered for.

A variant is one buyable version of a product, such as the Aska sofa in grey or in sage (Salbei). Each variant carries its own options, price and stock, and the product holds what they share:

tests/fixtures/home/catalog.jsonl, SOFA-ASKA-2 (trimmed)
{
    "type": "product",
    "id": "SOFA-ASKA-2",
    "title": { "de": "Aska 2-Sitzer-Sofa aus Samt", "en": "Aska two-seater velvet sofa" },
    "categories": ["wohnen/sofas"],
    "attributes": { "seats": 2, "width": "164 cm", "upholstery": "Samt" },
    "varies_by": ["color"],
    "variants": [
        {
            "id": "SOFA-ASKA-2-GRAU",
            "attributes": { "color": "Grau" },
            "price": 749.0,
            "availability": "in_stock",
            "stock": 12
        },
        {
            "id": "SOFA-ASKA-2-SALBEI",
            "attributes": { "color": "Salbei" },
            "price": 749.0,
            "sale_price": 649.0,
            "availability": "in_stock",
            "stock": 4
        }
    ]
}

varies_by names the attributes the variants differ by, and no two variants share the same values of them. A product without variants is its own single variant, with its offer on itself. An export with one row per variant, such as a CSV file, groups its rows into products by a parent column (Importing and mapping).

Reference: varies_by · variants

Attributes that differ per variant

An attribute at level: variant may differ between a product's variants, such as the home store's color and size:

tests/fixtures/home/attributes.json (trimmed)
{ "attributes": [{ "code": "color", "type": "option", "level": "variant" }] }

Every other attribute belongs to the product, the default level. The level tells facets and filters that one product may hold several values at once. A release without attributes.json derives it: an attribute the catalog writes on variants becomes a variant's.

Reference: level

A filter picks the variant

A tile stands for the whole product, every color included, until the shopper chooses a variant's value. Then it shows the first variant that meets every choice, and names it in variant:

Terminal
curl -s http://127.0.0.1:7800/v1/search -H 'Content-Type: application/json' \
  -d '{"on": "category_page", "category": "wohnen/sofas", "filters": {"color": "green"}}' \
  | jq -c '.sections[] | select(.type == "product") | .hits[] | {entity, variant, color: .fields["attributes.color"]}'
200 · 4.4 ms · release b25a6aaa
{"entity":"product:SOFA-ASKA-2","variant":"SOFA-ASKA-2-SALBEI","color":"Salbei"}
{"entity":"product:SOFA-LUND-3","variant":"SOFA-LUND-3-MOSS","color":"Moosgrün"}

Sage (Salbei) and moss green (Moosgrün) both belong to the group green. Each tile takes its variant's values, and its title, URL and photos where the variant has its own, so the Aska shows sage. Without a filter, variant is left out and the Aska's tile lists both colors.

A facet counts tiles, so with one tile per product a sofa counts once, however many of its variants match. Where variants differ, some counts can only be upper bounds, and the answer marks them (Upper bounds).

Reference: variant

A tile per product, variant or color

listing in types.json says what one tile stands for:

types.json
{ "types": [{ "type": "product", "listing": { "axis": "color" } }] }
  • "product", the default: one tile per product.
  • "variant": one tile per variant, with the variant's own offer.
  • { "axis": "color" }: one tile per value of an attribute the variants differ by. The bed BETT-NORA lists twice: grey, which comes in three sizes, and sage.

A finer tile shows its first variant's title, URL and photos, and a product that does not vary by the axis stays one tile. The axis is one option, quantity or boolean at level: variant. Changing listing rebuilds the indexes in an index run.

Reference: listing

Next

On this page