Commerce & Orders
Product Card
The shop catalog grid for retail/e-commerce apps. Renders products grouped into sections by category, with price, description, tags, and stock-aware badges. Deliberately separate from Menu Item Card, which is restaurant/dish shaped (allergens, spice level, combos) — use Product Card whenever you’re selling physical goods instead of food.
Tapping a product routes to detailScreenId, read by Product Detail.
Falls back to a generic starter catalog on the builder canvas so it never renders empty.
Available on all plans.
Four things worth knowing
Auto-grouped by category
Products are bucketed into sections by category in first-seen order. With a single category, section headers are skipped entirely.
Stock-aware badges
Below lowStockThreshold shows “Only X left”; at zero stock the card dims, disables tapping, and shows “Out of stock”.
Full product detail forwarded on tap
Tapping a card passes title, price, image, tags, stock, variants, and sizes as navigation params to detailScreenId — Product Detail reads all of it from there.
Category filter support
activeCategoryFilter narrows the list to one category, useful when pairing with a separate category selector component.
Note: products are managed from Admin Product Manager, not from this component’s props — items only serves as a builder-canvas placeholder.
Find it, drop it, wire the flow
Where to find itAdd it to your Shop screen
- Component picker → Commerce & Orders → Product Card.
- Place it on your home/shop screen, typically below a hero banner.
- Set
detailScreenIdto a screen containing a Product Detail component.
Before you publishThree things to check
- Add real products via Admin Product Manager so the catalog isn’t empty.
- Navigation wiring:
detailScreenIdmust point at a screen with Product Detail. - Set
lowStockThresholdand currency to match your store.
Data, navigation, and content
| Prop | Type | Default | Description |
|---|---|---|---|
items | array | [] | Builder-canvas placeholder only — live data comes from the Products API. |
currencyCode | select | EUR | Displayed currency for product prices. |
layout | horizontal / vertical | horizontal | Image-left-text or image-top-text card orientation. |
lowStockThreshold | number | 5 | Stock count at or below which the “Only X left” nudge appears. |
detailScreenId | screen-select | ” | Shared target screen every product navigates to on tap. |
activeCategoryFilter | string | unset | Optional — restricts the grid to a single category. |
showPrice, showDescription, showTags, showImage, showBadge, showStock | boolean | true | Per-field visibility toggles. |
customWidth, customHeight | runtime sizing | Builder/runtime dependent | Controls Review parity and viewport fit. |
Make it yours
Most visual customisation lives in Builder style props. Keep component defaults in sync with registry defaultProps when updating branding tokens.
| Prop | Default | What it controls |
|---|---|---|
backgroundColor, cardBackgroundColor | Theme defaults | Outer container and card surfaces. |
titleColor, priceColor, descriptionColor | Theme defaults | Text hierarchy across each card. |
tagBackgroundColor, tagTextColor | Theme defaults | Tag chip styling. |
badgeBackgroundColor, badgeTextColor | Theme defaults | Promotional badge (e.g. “New”, “Bestseller”). |
stockLowColor, stockOutColor | #F59E0B, #EF4444 | Low-stock and out-of-stock pill colors. |
imageSize, imageBorderRadius, cardBorderRadius, spacing | Component defaults | Sizing and shape of the grid. |
fontFamily, titleFontSize, priceFontSize | Component defaults | Typography family and scale. |
Common mistakes to avoid
Use Product Card for goods, not food
If you’re building a restaurant/café app, use Menu Item Card instead — it supports allergens, spice level, and combos that Product Card intentionally omits.
Seed products before publishing
An empty catalog shows a “No products yet” state. Use Admin Product Manager’s sample-product seeding to get real, editable content quickly.
Category names drive section headers
Keep category names consistent across products (e.g. always “apparel”, not “Apparel” and “apparel”) so items group into one section instead of two.
One detail screen for every product
detailScreenId is shared across all items — the Product Detail screen reads which product was tapped from navigation params, not from separate per-item screens.