settings.header + settings.description)Reusables\\ProductGridItem\\DefaultcollectionUrlviewItemList event when the carousel enters the viewport{
"products": [
{
"vatIncluded": true,
"vatRate": 25,
"reducedVatRate": 5,
"unitText": "Sample text",
"isMpnVisible": true,
"isSkuVisible": true,
"title": "Sample product title",
"description": "<p>Sample description</p>",
"alias": "sample-product-alias",
"status": "Active",
"brandId": "Brand Id",
"categoryId": "Category Id",
"categoryName": "Sample category name",
"categoryLink": "/category/sample",
"tags": [
"sample-tag",
"..."
],
"pathCategories": [
"Path Category Id",
"..."
],
"availability": "Available",
"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": 155,
"minPrice": 120,
"maxRetailPrice": 30,
"minRetailPrice": 10,
"updateDate": "2026-01-01T00:00:00.0000000+00:00",
"insertDate": "2026-01-01T00:00:00.0000000+00:00",
"variantCount": 3,
"additionalFeatures": {
"icoTags": [
{
"id": "IcoTag Id",
"name": "Sample text"
},
"..."
]
},
"searchAttributes": [
"Sample text",
"..."
],
"productVariants": [
{
"quantityConstraints": {
"additive": {
"minimum": 1,
"maximum": 999999,
"step": 1,
"isValid": true
},
"absolute": {
"minimum": 1,
"maximum": 999999,
"step": 1,
"isValid": true
}
},
"id": "Variant Id",
"mediaItem": {
"id": "Media Item Id"
},
"title": "Sample text",
"mpn": "Sample text",
"sku": "Sample text",
"initialPrice": 33,
"unitPrice": 30,
"price": 30,
"quantity": 0,
"retail": {
"initialPrice": 33,
"price": 30,
"unitId": "(UNDEFINED)",
"salesUnitId": "Sales Unit Id",
"unitPrice": 30
},
"dimension1ItemId": "Attribute Item Id",
"dimension2ItemId": "Attribute Item Id",
"sellOutOfStock": true,
"requiresShipping": false,
"translation": {},
"canOrder": true,
"additionalFeatures": {},
"bundleItems": [],
"shoppingLists": [],
"startQuantity": 1,
"finalPriceText": "Sample price text",
"finalPrice": 30,
"originalPriceText": "Sample price text",
"originalPrice": 33
},
"..."
],
"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
},
"..."
],
"brand": {
"name": "Sample text",
"link": "/brand/sample",
"image": {
"link": "https://example.com/media/sample.jpg"
}
},
"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": "Items",
"usedAsFilter": false,
"displayOnProduct": true,
"displayOnList": true,
"displayOnCompare": true,
"items": [
{
"id": "Attribute Item Id",
"value": "Sample text"
},
"..."
]
},
"startPriceText": "Sample price text",
"startPrice": 10,
"hasPriceRange": true,
"inWishlist": false
},
"..."
],
"collectionUrl": "/collection/sample",
"name": "ProductsCarousel",
"view": "Default",
"section": "SectionA",
"settings": {
"collectionIds": [
"Collection Id",
"..."
],
"buttonText": "Sample button text",
"description": "<p>Sample description</p>",
"displayLinkToCollection": true,
"backgroundColor": false,
"layoutMode": "Inline",
"inlineContentAlignment": "Left",
"id": "Component Id",
"section": "SectionA",
"type": "NoirProductsCarousel",
"name": "ProductsCarousel",
"configuredInContentApi": true,
"view": "Default",
"displayName": "Sample text",
"cssClass": "",
"header": "Sample text",
"alignment": "Left"
},
"translations": {
"clickToLearnMoreAbout": "Sample text",
"productsCarousel": "Sample text"
}
}settings.idproducts[]settings.cssClasssettings.header (if empty, the title is omitted; translations.productsCarousel becomes the list name for GA)settings.descriptionsettings.displayLinkToCollectionsettings.buttonTextcollectionUrlsettings.layoutMode (Inline or FullWidth)settings.inlineContentAlignment (used only when layoutMode == "Inline")settings.backgroundColorsettings.alignment (Left, Center, Right)translations.*settings.CarouselAutoplay (boolean)true, Swiper autoplays through slides automatically.settings.CarouselAutoplayDelay (number)3000.settings.CarouselPauseOnHover (boolean)true (default), autoplay pauses when the user hovers over the carousel.settings.CarouselNavigation (string enum)'Dots'.Dots, Arrows, Both.settings.Animation (string enum)'None'.None, WordsFade, SlideTrain, FadeStagger, RiseStagger..swiper:not(.swiper-initialized) .swiper-slide rule, with or without an animation. When settings.Animation is not None, the section is also rendered with productsCarousel--loading, which covers the header and text until the animation starts. See ThemeClasses.settings.Animation is not None, the section also gets productsCarousel--anim plus one of productsCarousel--anim-wordsFade, --anim-slideTrain, --anim-fadeStagger or --anim-riseStagger.Components/ProductsCarousel/Default.js exposes a global object:<section
x-data='productscarouseldefault.initComponent("{{ id }}", "{{ layoutMode }}", {{ products | serialize | escape }}, "{{ header | default: model.Translations.ProductsCarousel }}", {{ carouselAutoplay }}, {{ carouselAutoplayDelay }}, {{ carouselPauseOnHover }}, "{{ carouselNavigation }}")'
>swiperInit(...) even if there’s only one product; the template itself prevents rendering when empty.headerTitle consistent with the visible header, because it’s used as the GA4 list name.productsCarousel--loading, then calls initAnimation(swiper, section) on the next animation frame.viewItemList when 25% of the carousel is visible.elementInView("#products-carousel-" + id, ...) which expects the DOM id to match the Liquid template.prepareListProducts(products).productsCarousel--anim.WordsFade, it first wraps each word of the header and description with splitWords(root, startIndex). It then sets --pc-step (the delay between words, at most 60 ms) and --pc-btn-delay on the section.anim-ready, then waits until 30% of the section (or 30% of the viewport height) is visible. At that point it adds is-inview and marks the visible slides with is-animated and a --pc-i index used for staggering.#products-carousel-<id>.#products-carousel-<id>..swiper-pagination-<id>.layoutMode:FullWidth → 4slidesPerView.< 1024: 1 per view>= 1024: 2 per view>= 1440: slidesPerView (3 or 4)swiper-pagination-{{ id }}), it’s used as a selector.Reusables\\ProductGridItem\\DefaultelementInView(...)prepareListProducts(...)sendGAEvent(...)products is missing/empty.colorExists for ProductGridItem.listName is settings.header when present, else translations.productsCarousel.alignmentClass from settings.alignment.sectionClasses from:layoutMode, inlineContentAlignment)settings.cssClasssettings.backgroundColorproduct.dimension1.type == "Color" or product.dimension2.type == "Color".