ProductListItem reusable renders a product card in “list view” (row layout), typically used in catalog/search pages when the user switches from Grid to List. It supports:Components/FilterList/Default.liquid when view == 'List':{% render 'Reusables\\ProductListItem\\Default',
product: product,
modelId: id,
colorExists: colorExists,
listName: listName,
position: forloop.index0
%}productmodelIdmodelId-product.id) for DOM scoping.colorExistslistNamepositionproductImage from product.mediaItems[0] when available.x-data='productlistitemreusabledefault.initComponent({{ product | serialize | escape }}, "{{ Reusables.ProductListItem.Translations.AddToCartErrorMessage }}", "{{ Reusables.ProductListItem.Translations.UpdateProductQuantityErrorMessage }}")'/product/{{ product.alias }} and sends GA select-item via sendSelectEvent(...).product.icoTags exists, it renders label badges (desktop and mobile layouts).Reusables/ProductComparisonButtonReusables/WishlistButtonReusables/ShoppingListsButtonGlobalData.Settings.ShowProductComparisonGlobalData.Settings.EnableWishlistGlobalData.Settings.EnableShoppingListsproduct.brand.* exists it renders a brand badge (image when available, otherwise text).product.categoryName / product.categoryLink (when present).product.title and links to /product/{{ product.alias }}.colorExists is true and the product has a Color dimension with multiple variants, it shows up to 3 color dots and a “+N” indicator.GlobalData.Settings.noImage.link or /Assets/images/no-image.svg.{
"id": "Product Id",
"title": "Sample title",
"alias": "sample",
"categoryName": "Sample text",
"categoryLink": "/category/sample",
"mediaItems": [
{
"id": "Media Id",
"link": "https://example.com/sample",
"position": 0,
"alt": "Sample text",
"mediaType": "Image"
},
...
],
"icoTags": [
{
"id": "Tag Id",
"name": "Sample text",
"backgroundColor": "Sample text",
"textColor": "Sample text",
"icon": { "link": "https://example.com/sample" }
},
...
],
"brand": {
"name": "Sample text",
"link": "/brand/sample",
"image": { "link": "https://example.com/sample", "alt": "Sample text" }
},
"dimension1": {
"type": "Color",
"name": "Sample text",
"items": [ { "id": "Dim Item Id", "value": "Sample text", "textColor": "Sample text" }, ... ]
},
"dimension2": {
"type": "Size",
"name": "Sample text",
"items": [ { "id": "Dim Item Id", "value": "Sample text" }, ... ]
},
"productVariants": [
{
"id": "Variant Id",
"dimension1ItemId": "Dim Item Id",
"dimension2ItemId": "Dim Item Id",
"finalPrice": 25,
"finalPriceText": "25,00 €",
"originalPrice": 35,
"originalPriceText": "35,00 €",
"canOrder": true,
"sellOutOfStock": false,
"quantity": 2,
"minOrderQuantity": 1,
"orderQuantityStep": 1
},
...
],
"startPrice": 25,
"startPriceText": "25,00 €",
"hasPriceRange": false,
"inWishlist": false
}Default.liquid):product.id, product.title, product.aliasproduct.categoryName, product.categoryLinkproduct.mediaItems[0].link, product.mediaItems[0].altproduct.icoTags[] (label rendering)product.brand.name, product.brand.link, product.brand.image.link, product.brand.image.altproduct.productVariants (size and conditional blocks)product.dimension1, product.dimension2 and nested .type, .name, .items[] (mobile color dots)productlistitemreusabledefaultx-data="productlistitemreusabledefault.initComponent(product, addToCartErrorMessage, updateProductQuantityErrorMessage)"{{ product | serialize | escape }}). Keep the product payload reasonably sized.colorDimKey / otherDimKey.updateSelectedVariant().handleClickEvents().isMobile on resize.isProductSection is true, enables sticky/scroll helpers.selectItem for the clicked product.selectItem and then navigates to /product/${product.alias}.updateSelectedVariant().selectedVariant and selectedVariantIndex.updateQuantity(...) using quantity constraints.getActiveImage(...) (used in product section contexts).servicesreusabledefault.addToCart(...).groupVariant to add a specific variant (used by some UI modes).$store.toast to show errors.quantityConstraints.additive.isValid among matching variants.stockAvailability.label.isProductSection === true).quantity using quantityConstraints.additive.step and min/max.checkQuantity is true, calls servicesreusabledefault.updateProductQuantity(...) with an Axios cancel token.$store.toast on failures.$store.toastservicesreusabledefault.addToCart(...)servicesreusabledefault.updateProductQuantity(...)Reusables/ProductListItem/Default.liquidReusables/ProductListItem/Default.jsReusables/ProductListItem/Default.jsonReusables/ProductComparisonButton/DefaultReusables/WishlistButton/DefaultReusables/ShoppingListsButton/Defaultproduct.mediaItems[0] is an image; for best results the first media item should be an Image.colorExists affects whether the mobile color-dot block or a placeholder is shown.