Commmerce Docs

Overview

The card reads a product JSON object from data-product (typically injected by <mmm-loop> as {{item}}), creates a per-product store keyed by the product's slug, and renders its children via a shadow-DOM slot. Each child reads from the store — no per-child API calls.

Card dimensions are responsive per breakpoint: the most-specific value wins for the current viewport ({bp}-card-height / {bp}-card-widthcard-height / card-width → default). The component re-applies CSS on resize whenever the active breakpoint changes.

Breakpoint thresholds: mobile ≤ 430px, tablet ≤ 768px, desktop ≤ 1280px, xl above.

When to use

  • Collection & category product grids.
  • Search-result listings.
  • Related / recently-viewed carousels.
  • Anywhere you want product children to share data without each one fetching.

Quick start

<script src="https://v2-api-production.commmerce.com/api/v1/web-component/commmerce-sdk.js?store=sample-store"></script>

<mmm-product-card data-product='{"slug":"classic-tee","name":"Classic Tee","price":29}' card-height="33.125rem">
  <mmm-product-media view-mode="dual-image"></mmm-product-media>
  <mmm-product-title></mmm-product-title>
  <mmm-product-price></mmm-product-price>
  <mmm-product-variants></mmm-product-variants>
  <mmm-product-add-to-cart></mmm-product-add-to-cart>
</mmm-product-card>

Attributes

AttributeTypeDefaultDescription
data-productJSON stringRequired. Product object — must include slug. Usually injected by <mmm-loop> as data-product="{{item}}". Drives the per-product store the children read from.
card-heightstringautoBase card height — falls back when no per-breakpoint value matches.
card-widthstring100%Base card width.
card-backgroundstringtheme product bg / transparentCard background colour.
xl-card-heightstringCard height for viewports > 1280px.
desktop-card-heightstringCard height for 768px–1280px.
tablet-card-heightstringCard height for 430px–768px.
mobile-card-heightstringCard height for ≤ 430px.
xl-card-widthstringCard width for viewports > 1280px.
desktop-card-widthstringCard width for 768px–1280px.
tablet-card-widthstringCard width for 430px–768px.
mobile-card-widthstringCard width for ≤ 430px.
custom-cssstringExtra CSS appended inside the card's shadow DOM. Scoped — does not leak out.
classstringStandard HTML class list.

Slots

Default slot — accepts any <mmm-product-*> child. Children read their data from the shared per-product store; you do not pass data-product to each child individually.

Events

EventTargetPayload
product-store-readyelement{ slug: string, store: object }

Fires after the per-product store has parsed data-product and is ready for child subscriptions.

Live preview

store sample-store tag <mmm-product-card>

Examples

1. Inside a loop

<mmm-data-source api="product.getProductList" response-key="grid" payload-page-size="12">
  <mmm-loop data="{{window.PRODUCT_RESPONSE_GRID.products}}">
    <mmm-product-card data-product="{{item}}" desktop-card-height="32rem" mobile-card-height="24rem">
      <mmm-product-media></mmm-product-media>
      <mmm-product-title line-clamp="2"></mmm-product-title>
      <mmm-product-price></mmm-product-price>
    </mmm-product-card>
  </mmm-loop>
</mmm-data-source>

2. Per-breakpoint width

<mmm-product-card
  data-product='{"slug":"classic-tee","name":"Classic Tee","price":29}'
  xl-card-width="20rem"
  desktop-card-width="18rem"
  tablet-card-width="16rem"
  mobile-card-width="100%">
</mmm-product-card>

3. Listen for store-ready

document.querySelectorAll('mmm-product-card').forEach(card => {
  card.addEventListener('product-store-ready', (e) => {
    console.log('Ready:', e.detail.slug);
  });
});