Create engaging product displays with variant selection and media integration
After completing this page, you should be able to:
- Implement variant switching functionality on a product detail page, including displaying the master variant by default and dynamically updating product details and media based on user selection, leveraging the data structure of the Product Projection API.
Displaying Product Variants
In Composable Commerce, each Product Projection includes a Master Variant along with an array of the other variants. The Master Variant is the default version of the Product and is typically displayed at the default selected variant on the product detail page and other pages, such as the product listing page (PLP). Additional variants represent alternate configurations—such as different sizes, colors, or styles—that the Customer can select.
When rendering the product and its variant options, a key consideration is how to handle stock availability. You need to decide whether customers should be able to select and add variants to their cart even if they are out of stock for the relevant inventory supply channels associated with your website or app (for example, allowing backorders or pre-orders). If unavailable variants should not be selectable, then you may use the availability object, which will tell you what inventory is present for each Variant per Channel.
storeProjection
will also filter out InventorySupply
Channels that don’t belong to the Store.Code context and API response
Before building variant switching logic, retrieve a Product via the endpoint we've previously discussed. In the response, inspect the following:
- The
masterVariant
– which holds the primary display version of the Product. - The
variants[]
array – which contains other Variants.
"Cotton Silk Bedsheet"
might have:- Master Variant (Default)
id
: f955d965-11be-4bf5-a552-5328852c9d3asku
:"CSKW-093"
key
:"cottonSilkBedsheet01"
prices
: AUD and NZDattributes
: Size = Queen, Color = Whiteimages
: Main display image
- Additional variants (
variants[]
in the response) - 8 additional variants with unique
sku
,attributes
,prices
, andimages
. - Attributes might differ (for example, Size = Twin, King), allowing user-driven selection.
Best practices for variant switching
A well-designed variant switching interface allows users to explore different configurations of a product—such as size, color, or material—without navigating away or reloading the page. Below are the recommended best practices to help you build a seamless variant selection experience:
Display the Master Variant by default
- Initial load experience: always show the
masterVariant
as the default selection when the product detail page is first rendered. This ensures customers see a complete Product representation right away. - Content fallback: use the
masterVariant
details—such as price, images, and attributes—as your baseline product display before any user interaction. - Visual cue: indicate that this is the default selection, for example by pre-selecting a button, tag, or dropdown.
Offer clear and intuitive selection controls
- UI options:
- Use dropdowns for attributes like size or material.
- Use swatches or buttons for colors or styles.
- Group selectors if there are multiple variant attributes (for example, Size + Color).
- Visual feedback:
- Highlight the currently selected variant.
- Deactivate or gray out options for out-of-stock variants (based on availability).
- Accessibility:
- Ensure that selection elements are keyboard-accessible and screen reader-friendly.
Manage variant state effectively
- Selected variant: add a URL query parameter that specifies the current selected variant. This might use the Variant ID, SKU or key. For example:
/p/charlie-armchair?variant=3
/p/charlie-armchair?sku=abc
Dynamically update Product details on variant selection
When a new variant is selected:
- Price: update the displayed price using the embedded
price
field, which is already resolved based on price selection context (currency, country, Store, Channel). - Images: replace or update product images based on the variant’s image set.
- Attributes: refresh UI sections that show size, color, material, finish, or other variant-specific attributes.
- Availability: check
availability.isOnStock
andavailability.channels
to display accurate stock messages or deactivate the Add to Cart option if out of stock.
Handle edge cases
- Missing attributes: not all variants may have the same attribute set. Provide fallbacks or hide empty fields.
- Unavailable combinations: if a combination of attributes doesn’t exist (for example, Blue color + King size), prevent users from selecting it or show a relevant message.
- Performance optimization: avoid re-fetching the full product when the customer selects a different Variant option. Use the data already available in the
Product Projection response
.
Example logic
The following is a pseudocode snippet to illustrate the logic:
// Assume the 'product' object is the API response containing masterVariant and variants
let selectedVariant = product.masterVariant; // Display the master variant by default
// Function to render the product details based on the selected variant
function renderProductDetails(variant) {
// Update the UI components with variant.price, variant.images, variant.attributes, etc.
console.log('Displaying variant:', variant);
}
// Example UI: Creating buttons for each variant
product.variants.forEach((variant) => {
const button = document.createElement('button');
// For instance, display size attribute as the button text
const sizeAttribute = variant.attributes.find((attr) => attr.name === 'size');
button.innerText = sizeAttribute ? sizeAttribute.value['en-US'] : 'Select';
button.onclick = () => {
selectedVariant = variant;
renderProductDetails(selectedVariant);
};
document.getElementById('variant-selector').appendChild(button);
});
// Initially render the master variant details
renderProductDetails(selectedVariant);
Key takeaways
- Master Variant as the default display: the
masterVariant
is always the primary variant returned by the API and should be shown by default when the product detail page loads. It includes essential product data like the main price, primary image, and core attributes—offering customers a complete and immediate view of the product before any interaction. - Dynamic variant switching: allow users to interactively select from available variants (for example, size, color, or material). This interaction should trigger a real-time UI update to reflect the selected variant’s details—such as price, availability, and images—without requiring additional API calls, since all variant data is already included in the initial product projection response.
- Price context & Embedded Prices: when using Embedded Prices, the API response includes only those prices that match the specified context—such as
priceCurrency
,priceCountry
,priceChannel
, andstoreProjection
. This ensures that the displayed price is precise and relevant to the customer's regional and store-specific configuration. - Inventory awareness: the
availability
field in the response provides both global and channel-specific stock levels. Use this information to enable or deactivate purchase options and to display accurate stock status messages (for example, In Stock, Out of Stock, or Available in Store X). - Locale-driven data: the Product’s localized fields—such as
name
,description
, andslug
—are returned based on the specifiedlocaleProjection
or Store configuration. This ensures that users see product content in their preferred language, enhancing both usability and regional relevance.
By understanding and leveraging how Product Variants are structured in the Product Projection API, you can deliver a highly interactive and personalized product detail page. Showing the Master Variant by default, combined with real-time variant switching, contextual pricing, inventory visibility, and localized content, ensures your product detail page provides a seamless and engaging shopping experience for every customer at Zen Electron.
Product media
Leveraging Composable Commerce’s robust asset management capabilities allows you to store, manage, and deliver these media assets efficiently—ensuring fast load times and a responsive user experience.
Images and assets belong to the variants and so each variant might have different images.
Pseudocode example (BFF/Frontend integration)
assets
(or images
) field containing metadata such as URLs and dimensions.// Assume 'product' is the fetched product projection (For example, via fetchProductBySlug('charlie-armchair', 'en-US'))
const product = await fetchProductBySlug('charlie-armchair', 'en-US');
const masterVariant = product.masterVariant;
// Extract images from the master variant's assets field.
// If you also store videos, you can use masterVariant.assets.
const assets = masterVariant.images;
// Function to render assets on the product detail page.
function renderAssets(assets) {
const container = document.getElementById('product-media-container');
assets.forEach((asset) => {
// Create an image element for each asset.
const img = document.createElement('img');
img.src = asset.url; // Set the image source URL.
img.alt = product.name['en-US']; // Set an alt text using the product name.
// Optionally, add interactive features such as zoom functionality.
img.style.width = '100%'; // Adjust width as needed.
container.appendChild(img);
});
}
// Call the function to render the assets on the product detail page.
renderAssets(assets);