Skip to main content

ProductListAddToCart

Description​

The action under a product card. For a simple product it is the Add to Cart button. For a product with variants (colour, size...) it is a Select options link to the product page, because the customer has to choose and a card cannot ask. Adding the card's own variant to the cart would put something in it the customer never picked.

Role in Theming​

Core's ProductListItemRender uses it, and a theme's own copy of that card should too. The rule "which action does this product get" then lives in one place, and your card only decides how the action looks.

ProductList still decides whether the action is offered at all (see ProductList). This component decides which action.

Import​

import { ProductListAddToCart, hasVariants } from '@components/frontStore/catalog/ProductListAddToCart';

Usage​

<ProductListAddToCart product={product} variant="outline" className="w-full" />

Props​

PropTypeRequiredDescription
productProductDataYesThe product the card shows. It needs sku, inventory.isInStock, url and variantGroupId.
variantButton variantNoThe look of the button or link, one of the shared Button's variants. Both actions take the same look.
sizeButton sizeNoOne of the shared Button's sizes.
classNamestringNoExtra classes, merged with the button classes (for example w-full).

Which action a product gets​

ProductRenders
Has no variant groupA Button, "Add to Cart" (and "Adding..." while it works). Errors show as a toast.
Has no variant group and is out of stockA disabled Button that says "Sold out", the word the product page's own button uses.
Belongs to a variant group (variantGroupId is set)An <a href={product.url} data-slot="button"> that says "Select options", even when the card's own variant is sold out: another variant may be in stock, and the card cannot tell. It is a link because it navigates, and data-slot="button" keeps it styled by everything that styles buttons.
Belongs to a variant group and has no urlNothing. There is nowhere to send the customer, and adding the variant is the one thing not to do.

hasVariants(product) is the rule on its own: it returns true when variantGroupId is set. It is the same rule core's product resolver and its "configurable" product filter use.

Translations​

It uses four strings, all translated in every shipped locale: Add to Cart, Adding..., Sold out and Select options. A theme's own copy of the card that reuses them needs no new translation rows.

Feeding it from your own list​

The card learns that a product has variants from variantGroupId, a plain column of the product (unlike variantGroup, which runs queries per product). Select it in the Product fragment of any list or widget you write, or its cards will offer Add to Cart for products that need a choice:

export const fragments = `
fragment Product on Product {
productId
name
sku
variantGroupId
price { regular { value text } special { value text } }
inventory { isInStock }
image { alt url }
url
}
`;