Product, Variant, and Item
Commerce Engine exposes three related models:variant_id: null.
Choose the listing operation
Public accessor
Browser SPA:Product listing page
Grouped products
Flattened Items
product_id and variant_id from the Item for Add to Cart. Use product and variant slugs from the response to construct stable URLs when available.
Category routes
Resolve the route slug to a category before issuing a scoped product query.Faceted search
Retrieve the exact current method signature from:Filter safety
When constructing filter strings from user-visible catalog values:- allow only known filter fields and operators
- escape quotes and backslashes in values
- do not concatenate arbitrary filter expressions supplied by the browser
- keep URL state separate from the compiled API filter
URL state
Store search and filter state in the URL so pages can be shared, refreshed, indexed where appropriate, and restored after back/forward navigation. Typical parameters:Request supersession
A slower previous request must not replace a newer query’s state. Use the data library’s cancellation signal or a request sequence:Faceted search with stale-response protection
Product detail page
product_id_or_slug; retrieve the exact operation contract before implementation rather than guessing the key.
Prefer the variants included in product detail. Call listProductVariants() only when the response omits them or the feature needs the dedicated operation.
Variant option model
Forhas_variant: true, option query parameters are the canonical state:
variant parameter can be derived or used to backfill missing option parameters, but it should not replace the customer-visible option state.
Resolve a variant
- Read option groups in
product.variant_optionsorder. - Normalize values consistently:
- color option → compare
value.name; usevalue.hexcodefor UI - single-select option → compare the string value
- color option → compare
- Match every selected option against
variant.associated_options. - Resolve a variant only when all required option keys are selected.
- Update displayed price, image, stock, SKU, and description from the resolved variant.
requiredOptionKeys from the normalized option groups rendered by the PDP. Keep a separate partial-selection matcher for disabling impossible choices; do not use a partial match as the resolved purchasable variant.
Disable impossible choices
For each displayed option value, check whether at least one variant matches the current partial selection and remains purchasable. Disable values that cannot lead to a valid selection. A variant is purchasable when:Add to Cart
Attributes versus variant options
Attributes enrich product data and power filtering/specification display. Variant options create distinct sellable variants. A product without variants can still expose color or single-select attributes that a brand wants to render with option-style UI. Keep one normalized display model, but make those values read-only and do not invent a variant ID. Avoid rendering the same key twice when an attribute overlaps a variant option.Pricing and customer groups
B2B stores can apply group-specific catalog pricing and promotions. Set authoritative customer-group context through the SDK’s supported headers/configuration rather than adding ad hoc parameters to every request. A public page without known customer-group identity should render the store’s public/default pricing. After login or group resolution, invalidate affected catalog queries.Reviews and recommendations
Read reviews publicly where allowed. Submitting a review is a session-bound write and can require a logged-in user and eligible order context. Use recommendation operations for:- similar products
- upsell products
- cross-sell products
SEO and structured data
A server-rendered or prerendered PDP should include:- product title and description
- canonical product URL
- social metadata and a valid product image when available
- Product JSON-LD with name, description, URL, SKU, price, currency, and availability
- AggregateRating only when the rating count and values are valid
- BreadcrumbList JSON-LD
JSON.stringify() without escaping <, >, and &.
Category pages should have unique titles, descriptions, canonical URLs, and useful not-found behaviour.
Rendering and performance
- prerender/cache public catalog routes according to the framework and catalog-change frequency
- use ISR or equivalent revalidation when appropriate
- parallelize independent reads
- provide fixed image dimensions or aspect-ratio containers
- render meaningful skeletons that match the final layout
- keep session bootstrap out of public rendering
- paginate full-catalog build discovery rather than assuming one page contains every route
- warn in build logs when catalog discovery fails; do not silently publish a partial route set
Failure handling
Distinguish:- successful response with no matching resource → confirmed not found
- 404 operation response → confirmed not found where contractually applicable
- timeout, 5xx, network error → recoverable upstream failure
- empty search results → valid empty state
Production checklist
Catalog skills and production examples
Use the Commerce Engine catalog skill for decision logic, the LLM-first reference for exact contracts, and the starters for integrated PLP/PDP patterns.