Purpose#
CollectionStructuredData emits Schema.org JSON-LD (CollectionPage wrapping an ItemList of Product) for a category/search/collection listing page, so search engines can produce category rich results and AI agents get the product set with item URLs.Where it's rendered#
Rendered from Components/FilterList/Default.liquid:{% render 'Reusables\CollectionStructuredData\Default', products: products, canonicalUrl: canonicalUrl, companyDomain: companyDomain, pageName: pageName, showPrices: showPrices, currencyCode: currencyCode %}
The list of products currently shown on the listing page.
Used both for the page's url and to derive the site origin for absolute product URLs.
Fallback used to derive the site origin when canonicalUrl isn't available.
Listing page title, used as CollectionPage.name.
Boolean; when false, per-item offers blocks are omitted.
ISO 4217 currency code (defaults to EUR when missing).
Model shape (storefront example)#
[
{
"title": "Sample product title",
"link": "/product/sample",
"sku": "Sample text",
"mediaItems": [{ "link": "https://example.com/sample.jpg" }],
"brand": { "name": "Sample brand" },
"stockAvailability": { "label": "InStock" },
"startPrice": 25,
"productVariants": [{ "finalPrice": 25 }]
}
]
Template behavior (Liquid + Alpine)#
Renders nothing when products is empty/missing.
Derives siteOrigin the same way as BrandListStructuredData (from canonicalUrl, falling back to companyDomain).
Builds each product's absolute URL from product.link: uses it as-is if it already contains ://, otherwise prefixes it with siteOrigin (handling both leading-slash and relative link shapes).
Resolves list price as product.startPrice, falling back to the first variant's finalPrice; offers is included only when showPrices is true and a price was resolved.
Availability per item comes from product.stockAvailability.label (OutOfStock → https://schema.org/OutOfStock, otherwise InStock).
Data contract (JS runtime)#
No client-side runtime state; all data is read directly from the Liquid render parameters at render time.JavaScript#
File: Reusables/CollectionStructuredData/Default.js
Exposes: collectionstructureddatareusabledefault (currently an empty object)The JSON-LD block is fully server-rendered; the global only reserves a unique name in the concatenated componentscripts.js bundle.Global Alpine stores#
None. This reusable does not read or update any Alpine store.Services / API calls#
None. All data (product list) is passed in as a render parameter; there are no client-side API calls.Dependencies#
Liquid: Reusables/CollectionStructuredData/Default.liquid
JS: Reusables/CollectionStructuredData/Default.js
Translations: Reusables/CollectionStructuredData/Default.json
Notes#
The numberOfItems/itemListElement count reflects only the current page's products (i.e. the current page size), not the collection's total count.
Modified at 2026-07-24 07:43:37