Skip to content

Render customizable options

Customizable options let shoppers choose add-ons or enter information such as a monogram, instructions, or a preferred date. On the product details page (PDP), the ProductCustomizableOptions container renders choices and shopper-input fields from the product’s ac_customizable_options attribute.

Before customizing the layout, review these topics:

You’ll import the ProductCustomizableOptions container, add a mount element to your custom Product Details block, and render it alongside the other PDP containers. In an existing storefront block, reuse its customizable-options mount element instead of adding another one.

Place the imports at the top of your block’s JavaScript file. Run the mounting and rendering code inside its decorate(block) function, after the PDP initializer has loaded product data.

import { render as pdpRendered } from '/@dropins/storefront-pdp/render.js';
import ProductCustomizableOptions from '/@dropins/storefront-pdp/containers/ProductCustomizableOptions.js';

Add a wrapper element for the container, alongside your existing Product Details markup (for example, next to the gift card options slot):

const fragment = document.createRange().createContextualFragment(`
<div class="product-details__right-column">
<div class="product-details__gift-card-options"></div>
<div class="product-details__customizable-options"></div>
<div class="product-details__configuration">
<!-- ...options, quantity, buttons... -->
</div>
</div>
`);
const $customizableOptions = fragment.querySelector('.product-details__customizable-options');
block.append(fragment);

Render ProductCustomizableOptions into the slot alongside your other containers. It’s safe to include in the same Promise.all batch as the rest of your Product Details containers.

await Promise.all([
// ...other containers (gallery, header, price, options, quantity)...
pdpRendered.render(ProductCustomizableOptions, {})($customizableOptions),
]);

The container renders when either selectable or shopperInput contains options. If both are empty, the slot stays empty. See the container reference for configuration options.

When a shopper selects a value, the container adds its encoded custom-option/<optionId>/<valueId> UID to the PDP configuration’s optionsUIDs. Deselecting the value removes its UID. Read this configuration with getProductConfigurationValues. The cart drop-in uses the same optionsUIDs, so no extra mapping is needed before calling addProductsToCart.

Text, date, and time inputs update enteredOptions instead of optionsUIDs:

const enteredOption = {
uid: 'Y3VzdG9tLW9wdGlvbi80',
value: 'My monogram',
};

Use the encoded UID from shopperInput[].id without changing it. Clearing the input removes only its entry. Other input values, selected options, and quantity remain unchanged. The cart API accepts these entries as enteredOptions and forwards them as GraphQL entered_options.

The standard storefront already forwards the PDP configuration to the cart. In a custom add-to-cart handler, use the same configuration rather than reconstructing option UIDs:

import * as pdpApi from '/@dropins/storefront-pdp/api.js';
import { addProductsToCart } from '/@dropins/storefront-cart/api.js';
const values = pdpApi.getProductConfigurationValues();
if (values && pdpApi.isProductConfigurationValid()) {
await addProductsToCart([{ ...values }]);
}

The configuration check does not enforce required customizable options. Do not rely on it to prevent submission of an empty required field.

For text fields and multiline text, positive integer range.from and range.to values set the minimum and maximum lengths. A maximum of 0 means unlimited.

Date, local date-time, and time controls do not apply text length limits or timezone conversion. They use the cart-compatible formats documented in the container reference. File options appear disabled with a message that file uploads are not supported.

Do not mount the standalone container when your page already renders customizable options through ProductDetails.

For a full integration reference, see the storefront Product Details block .

Check that selected and entered options reach the cart:

  1. Open a product that has customizable options. Confirm that each configured option appears once.
  2. Select a dropdown or radio value, then select several checkbox values. Confirm that getProductConfigurationValues().optionsUIDs contains their encoded value UIDs.
  3. Enter text and a date or time. Confirm that enteredOptions contains the encoded option UIDs and the expected string values.
  4. Clear one input field. Confirm that only its entry disappears from enteredOptions.
  5. Add the configured product to the cart and confirm that its selected and entered options are retained. Check that file controls remain disabled.
  6. Open a product without customizable options. Confirm that the slot stays empty.