Reusables\ProductGridItem\DefaultviewItemList only when the carousel enters the viewport (IntersectionObserver-style helper){
"products": [
{
"vatIncluded": true,
"vatRate": 25,
"reducedVatRate": 5,
"unitText": "Sample text",
"isMpnVisible": true,
"isSkuVisible": true,
"title": "Sample product title",
"alias": "sample-product-alias",
"status": "Active",
"categoryId": "Category Id",
"categoryName": "Sample category name",
"categoryLink": "/category/sample",
"additionalCategoryIds": [],
"tags": [
"sample-tag",
"..."
],
"pathCategories": [
"Path Category Id",
"..."
],
"stockAvailabilityModelId": "Stock Availability Model Id",
"isBundle": false,
"id": "Product Id",
"companyId": "Company Id",
"link": "product/sample-product",
"mediaItems": [
{
"id": "Media Item Id",
"link": "https://example.com/media/sample.jpg",
"position": 0,
"alt": "sample.jpg",
"mediaType": "Image"
},
"..."
],
"maxPrice": 50,
"minPrice": 35,
"maxRetailPrice": 25,
"minRetailPrice": 25,
"updateDate": "2025-01-01T00:00:00.0000000+00:00",
"insertDate": "2025-01-01T00:00:00.0000000+00:00",
"variantCount": 24,
"additionalFeatures": {
"icoTags": [
{
"id": "IcoTag Id",
"name": "Sample text"
},
"..."
]
},
"searchAttributes": [
"Sample search attribute",
"..."
],
"productVariants": [
{
"quantityConstraints": {
"additive": {
"minimum": 1,
"maximum": 999999,
"step": 1,
"isValid": true
},
"absolute": {
"minimum": 1,
"maximum": 999999,
"step": 1,
"isValid": true
}
},
"id": "Variant Id",
"mediaItem": {},
"unitPrice": 25,
"price": 25,
"quantity": 0,
"retail": {
"price": 25,
"unitId": "(UNDEFINED)",
"unitPrice": 25
},
"dimension1ItemId": "Attribute Item Id",
"dimension2ItemId": "Attribute Item Id",
"sellOutOfStock": true,
"unitId": "Unit Id",
"requiresShipping": false,
"translation": {},
"canOrder": true,
"additionalFeatures": {},
"bundleItems": [],
"shoppingLists": [],
"startQuantity": 1,
"finalPriceText": "Sample price text",
"finalPrice": 25
},
"..."
],
"attributes": [
{
"attributeId": "Attribute Id",
"attributeItemId": "Attribute Item Id",
"attributeItemValue": "Sample text",
"name": "Sample text",
"slug": "sample-slug",
"usedAsFilter": false,
"displayOnProduct": true,
"displayOnList": true,
"displayOnCompare": true
},
"..."
],
"icoTags": [
{
"id": "IcoTag Id",
"name": "Sample text",
"icon": {
"alt": "Sample text"
}
},
"..."
],
"labels": [
{
"id": "Label Id",
"name": "Sample text",
"icon": {
"alt": "Sample text"
}
},
"..."
],
"dimension1": {
"id": "Dimension Id",
"attributeId": "Attribute Id",
"name": "Sample text",
"translation": {},
"type": "Color",
"usedAsFilter": true,
"displayOnProduct": true,
"displayOnList": true,
"displayOnCompare": true,
"items": [
{
"textColor": "#000000",
"id": "Attribute Item Id",
"value": "Sample text"
},
"..."
]
},
"dimension2": {
"id": "Dimension Id",
"attributeId": "Attribute Id",
"name": "Sample text",
"translation": {},
"type": "Size",
"usedAsFilter": true,
"displayOnProduct": true,
"displayOnList": true,
"displayOnCompare": true,
"items": [
{
"id": "Attribute Item Id",
"value": "S"
},
"..."
]
},
"startPriceText": "Sample price text",
"startPrice": 25,
"hasPriceRange": false,
"inWishlist": false
},
"..."
],
"name": "LastVisitedProducts",
"view": "Default",
"section": "SectionA",
"settings": {
"id": "Component Id",
"section": "SectionA",
"type": "NoirLastVisitedProducts",
"name": "LastVisitedProducts",
"configuredInContentApi": true,
"view": "Default",
"displayName": "Sample text",
"cssClass": "(UNDEFINED)",
"header": "Sample text",
"alignment": "Left"
},
"translations": {
"lastVisitedProducts": "Sample text"
}
}settings.idcomp-{{ id }}products-carousel-{{ id }}.swiper-pagination-{{ id }}products[]products exists and products.size > 0.settings.cssClass(UNDEFINED).settings.headertranslations.lastVisitedProducts.settings.alignmentLeft (default)CenterRightinitComponent(id, products, headerTitle)id: component id (used to locate DOM nodes)products: serialized products array (used for analytics payload)headerTitle: header or translation fallback (used as GA listName)id, products, headerTitleinit()swiperInit(id)init()this.swiperInit(this.id)elementInView("#products-carousel-" + id, callback, { threshold: 0.25 })prepareListProducts(this.products)sendGAEvent("viewItemList", { listName: headerTitle, items })elementInView(...) is assumed to be a global helper (typically defined in Assets/js/theme.js). If it’s missing, analytics won’t fire (but the carousel still works).swiperInit(id)#products-carousel-<id>. If missing → return.slidesPerView = 1slidesPerView = 4loop enabled only if slides.length > 4spaceBetween = 24new Swiper(...) will throw.cart, toast, etc.elementInView(...)prepareListProducts(...)sendGAEvent(...)elementInViewprepareListProductssendGAEventproducts[] provided in the view model.colorExists flag.products is empty/missing, the entire section is not rendered.colorExists by checking if any product has:product.dimension1.type == 'Color' ORproduct.dimension2.type == 'Color'Reusables\ProductGridItem\Default to influence how variant color UI is rendered..swiper container with .swiper-wrapper and .swiper-slide items.swiper-pagination-{{ id }}{% render 'Reusables\\ProductGridItem\\Default', product: product, modelId: id, colorExists: colorExists, listName: listName, position: forloop.index0 %}listName) and position are passed down to the product card reusable.x-data='lastvisitedproductsdefault.initComponent(id, products, headerOrTranslation)'