Product card reference for Loomi AI for Shopify

Experience customization lets you personalize product cards in your storefront. Product cards are the main display units in the product grid, showing the image, title, price, and variant swatches for each result. Use the data attributes and EJS variables on this page to customize their markup, swatch selection behavior, and autosuggest appearance.

For page layout requirements, see HTML and EJS reference for Loomi AI for Shopify.

Product card component.

Data attributes

AttributeElementValueBehavior
data-br-actionProduct link, image linkproduct-card-product-linkhref navigation still works. Click additionally fires br-product-link-clicked for tracking in search or autosuggest. Doesn't change card content.
data-br-actionVariant swatchproduct-card-select-swatchClick selects that variant on the card. No navigation. Updates swatch styling, product image, title, prices, product link URL, and add-to-cart link to match the variant.
data-br-swatch-indexVariant swatch0..n-1 (number)Index in the visible swatch list. Must be the loop index over visibleSwatchItems.
data-br-actionOverflow +N or buttonproduct-card-toggle-variants-expandWhen showOverflowButton is true, click toggles between collapsed and expanded swatch rows. Collapsed shows only swatches that fit plus a +N button. Expanded shows all swatches and a control.

EJS variables

The productCard object exposes these fields:

FieldDescriptionData type
productRaw full product payload from Discovery. See ProductData below.ProductData
pidProduct ID.string
brandBrand name.string or undefined
titleEffective title. The selected variant overrides this when variants are enabled.string
thumbImageEffective image URL.string or undefined
priceEffective list price.number or undefined
salePriceEffective sale price.number or undefined
formattedPricePre-formatted list price.string or undefined
formattedSalePricePre-formatted sale price.string or undefined
hasDiscounttrue when both prices exist and salePrice < price.boolean
productUrlProduct detail page URL. Includes a variant query when applicable.string
addToCartHref/cart/add?id=… for the selected or first variant.string or undefined
displayVariantsWhether variant UI is enabled.boolean
swatchItemsAll swatches. See VariantSwatchItem below.VariantSwatchItem[]
visibleSwatchItemsSubset shown in the current collapsed or expanded state.VariantSwatchItem[]
selectedSwatchIndexIndex of the selected swatch.number
variantsExpandedWhether the overflow list is expanded.boolean
hiddenCountNumber of swatches hidden behind +N.number
showOverflowButtonWhether to render the overflow toggle.boolean

ProductData

ProductData is the raw product payload from Discovery, passed through as productCard.product. Discovery returns only the attributes you request in the widget's fl_fields parameter, so a field appears only when you include it (pid is always returned).

FieldDescriptionData type
pidProduct ID.string
titleProduct title.string
brandBrand name.string
descriptionProduct description.string
priceList price.number
price_rangePrice range for products with variants.number[]
promotionsActive promotions.string[]
sale_priceSale price.number
sale_price_rangeSale price range for products with variants.number[]
scoreDiscovery relevance score.number
thumb_imageThumbnail image URL.string or undefined
urlProduct detail page URL.string
variantsProduct variants.Variant[]

ProductData also accepts custom Discovery attributes. Define them in the widget's fl_fields parameter to make them available to your template.

VariantSwatchItem

VariantSwatchItem is a union type. Color swatches and image swatches use different shapes.

Color swatch (type: "color"):

FieldDescriptionData type
typeAlways "color".string
hexHex color value.string
labelSwatch label for accessibility and tooltips.string

Image swatch (type: "image"):

FieldDescriptionData type
typeAlways "image".string
urlSwatch image URL.string
labelSwatch label for accessibility and tooltips.string
fallbackHexBackground color shown while the image loads.string or undefined

Autosuggest product card limitations

Autosuggest renders product cards from its own Discovery API endpoint, which returns a reduced field set. When you template a product card for the Autosuggest dropdown, only these fields are available:

FieldDescriptionData type
pidProduct ID.string
titleProduct title.string
sale_priceSale price.number or undefined
thumb_imageThumbnail image URL.string or undefined
urlProduct detail page URL.string

References to any other productCard.* field render as empty in this context.

Example

<a
  href="<%= productCard.productUrl %>"
  data-br-action="product-card-product-link"
>
  <div>
    <% if (productCard.thumbImage) { %>
      <img src="<%= productCard.thumbImage %>" alt="<%= productCard.title %>" loading="lazy" />
    <% } else { %>
      <span>No image</span>
    <% } %>
  </div>
  <div>
    <% if (productCard.brand) { %>
      <div><%= productCard.brand %></div>
    <% } %>
    <h3><%= productCard.title %></h3>
    <% if (productCard.hasDiscount) { %>
      <div>
        <span><%= productCard.formattedSalePrice %></span>
        <span><%= productCard.formattedPrice %></span>
      </div>
    <% } else if (productCard.formattedSalePrice || productCard.formattedPrice) { %>
      <div>
        <span><%= productCard.formattedSalePrice || productCard.formattedPrice %></span>
      </div>
    <% } %>
  </div>
</a>
<% if (productCard.displayVariants && productCard.visibleSwatchItems.length) { %>
<div>
  <% productCard.visibleSwatchItems.forEach(function(item, idx) {
    let selected = idx === productCard.selectedSwatchIndex;
    let label = item.label || '';
  %>
    <% if (item.type === 'image') { %>
      <span
        title="<%= label %>"
        data-tooltip="<%= label %>"
        data-br-action="product-card-select-swatch"
        data-br-swatch-index="<%= idx %>"
        <% if (item.fallbackHex) { %>style="background-color: <%= item.fallbackHex %>"<% } %>
      >
        <img src="<%= item.url %>" alt="" loading="lazy" />
      </span>
    <% } else { %>
      <span
        style="background-color: <%= item.hex %>"
        title="<%= label %>"
        data-tooltip="<%= label %>"
        data-br-action="product-card-select-swatch"
        data-br-swatch-index="<%= idx %>"
      ></span>
    <% } %>
  <% }); %>
  <% if (productCard.showOverflowButton) { %>
    <button
      type="button"
      data-br-action="product-card-toggle-variants-expand"
      aria-label="<%= productCard.variantsExpanded ? 'Show fewer variants' : 'Show ' + productCard.hiddenCount + ' more' %>"
    >
      <%= productCard.variantsExpanded ? '−' : '+' + productCard.hiddenCount %>
    </button>
  <% } %>
</div>
<% } %>
<% if (productCard.addToCartHref) { %>
  <a href="<%= productCard.addToCartHref %>">
    Add to cart
  </a>
<% } %>


© Bloomreach, Inc. All rights reserved.