Product Block – Default¶
The Product Block is the primary card-style component used to display a single product in listing contexts such as category pages, search results, and recommendation rows. The Default variant is the standard full-featured version.
It shows the product image (switching per colour variant), name, category, price, a spec highlight, stock status, wishlist and compare actions, and colour swatches.
Preview¶
Add screenshots here
Place Figma design screenshots or browser screenshots in docs/assets/images/screenshots/product-block/ and reference them below.

Props¶
Top-level props¶
| Prop | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Unique product slug used as identifier |
name |
string |
Yes | Display name of the product |
category |
string |
Yes | Category label shown below the product name |
inWishlist |
boolean |
Yes | Whether the active variant is saved to the wishlist |
inCompare |
boolean |
Yes | Whether the active variant is added to the comparison list |
badge |
Badge |
No | Optional badge shown on top of the product image |
price |
Price |
Yes | Price data, including an optional sale price |
spec |
Spec |
No | A single highlighted specification (e.g. weight) |
stock |
Stock |
Yes | Stock availability status |
variants |
Variant[] |
Yes | List of colour variants, each with its own images and state |
Nested object props¶
Prop path: badge
| Field | Type | Required | Description |
|---|---|---|---|
label |
string |
Yes | Text displayed in the badge (e.g. "Nieuw", "Sale") |
visible |
boolean |
Yes | Whether the badge is rendered |
Prop path: price
| Field | Type | Required | Description |
|---|---|---|---|
currency |
string |
Yes | ISO 4217 currency code (e.g. "EUR") |
symbol |
string |
Yes | Currency symbol displayed in the UI (e.g. "€") |
regular |
number |
Yes | Regular (non-discounted) price |
sale |
number |
No | Sale price. When present, the regular price is shown as crossed out |
Prop path: spec
| Field | Type | Required | Description |
|---|---|---|---|
type |
string |
Yes | Spec category key used to look up a default icon (e.g. "weight") |
value |
number |
Yes | Numeric value of the spec |
unit |
string |
Yes | Unit label appended to the value (e.g. "gr", "mm") |
icon |
string \| null |
No | Override icon name. When null, the icon is resolved from type |
Prop path: stock
| Field | Type | Required | Description |
|---|---|---|---|
available |
boolean |
Yes | Whether the product is currently in stock |
label |
string |
Yes | Human-readable stock status label (e.g. "Op voorraad") |
Prop path: variants[]
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Unique identifier for this colour variant |
color |
string |
Yes | Hex colour value used to render the swatch (e.g. "#4A7C59") |
label |
string |
Yes | Human-readable colour name (e.g. "Forest Green") |
active |
boolean |
Yes | Whether this variant is currently selected. Exactly one variant should be true |
inWishlist |
boolean |
Yes | Whether this variant is saved to the wishlist |
inCompare |
boolean |
Yes | Whether this variant is added to the comparison list |
images |
Image[] |
Yes | One or more product images for this variant |
Prop path: variants[].images[]
| Field | Type | Required | Description |
|---|---|---|---|
src |
string |
Yes | Path or URL to the image file |
alt |
string |
Yes | Alt text describing the image for accessibility |
Visual States¶
The component adapts its appearance based on the prop values received.
| State | Condition | Visual effect |
|---|---|---|
| Badge | badge.visible: true |
A labelled badge is overlaid on the product image |
| On sale | price.sale is set |
Sale price shown prominently; regular price rendered as strikethrough |
| In wishlist | inWishlist: true (active variant) |
Heart icon rendered as filled/active |
| In compare | inCompare: true (active variant) |
Compare icon rendered as active |
| Out of stock | stock.available: false |
Stock label reflects unavailability (e.g. greyed out or with warning colour) |
| Active variant | variants[n].active: true |
The selected swatch is highlighted; the variant's images are displayed |
Behaviour¶
Wishlist and compare state is per variant
The inWishlist and inCompare fields exist on both the top-level product and on each individual variant object. The top-level values reflect the state of the currently active variant and are used to drive the UI icons. When the user switches to a different colour, the top-level values update to match that variant's state.
Colour swatch selection
Clicking a colour swatch sets the corresponding variant's active flag to true and all others to false. This triggers an image swap to show that variant's product images.
Spec icon fallback
When spec.icon is null, the component resolves an icon automatically based on the spec.type value (e.g. "weight" maps to a scale icon). An explicit spec.icon value overrides this fallback.
Example¶
Full example JSON
{
"id": "scarpa-ribelle-run-gtx",
"badge": {
"label": "Nieuw",
"visible": true
},
"name": "Scarpa Ribelle Run GTX",
"category": "Trailrunning schoenen",
"inWishlist": true,
"inCompare": false,
"price": {
"currency": "EUR",
"symbol": "€",
"regular": 249.95,
"sale": 224.95
},
"spec": {
"type": "weight",
"value": 180,
"unit": "gr",
"icon": null
},
"stock": {
"available": true,
"label": "Op voorraad",
"colorState": "state-green"
},
"variants": [
{
"id": "forest-green",
"color": "#4A7C59",
"label": "Forest Green",
"active": true,
"inWishlist": true,
"inCompare": false,
"images": [
{
"src": "/images/scarpa-ribelle-run-gtx-forest-green-1.jpg",
"alt": "Scarpa Ribelle Run GTX – Forest Green"
}
]
},
{
"id": "orange",
"color": "#E8673A",
"label": "Orange",
"active": false,
"inWishlist": false,
"inCompare": false,
"images": [
{
"src": "/images/scarpa-ribelle-run-gtx-orange-1.jpg",
"alt": "Scarpa Ribelle Run GTX – Orange"
}
]
},
{
"id": "black",
"color": "#1A1A1A",
"label": "Black",
"active": false,
"inWishlist": false,
"inCompare": false,
"images": [
{
"src": "/images/scarpa-ribelle-run-gtx-black-1.jpg",
"alt": "Scarpa Ribelle Run GTX – Black"
}
]
},
{
"id": "light-blue",
"color": "#A8C5DA",
"label": "Light Blue",
"active": false,
"inWishlist": false,
"inCompare": true,
"images": [
{
"src": "/images/scarpa-ribelle-run-gtx-light-blue-1.jpg",
"alt": "Scarpa Ribelle Run GTX – Light Blue"
}
]
}
]
}