Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Product Details Slots

The Product Details drop-in exposes slots on each composed container so you can customize specific UI sections. Use slots to replace or extend those container components.

See the containers overview for the official deprecation wording. The summary table includes a deprecated ProductDetails row so you can map legacy slot names during migration. Use the sections below for ProductAttributes, ProductGallery, ProductOptions, and ProductDetails (deprecated) slots. For default properties available to all slots, see Extending drop-in components. For Add to Cart, Add to Wishlist, and similar buttons, read Add to Cart and Add to Wishlist first, because that pattern is not covered by the slots in the table below.

Version: 3.0.2
ContainerSlotsDeprecated
ProductAttributesAttributesNo
ProductGalleryCarouselThumbnail, CarouselMainImageNo
ProductOptionsSwatches, SwatchImageNo
ProductDetails container (deprecated)Title, SKU, RegularPrice, SpecialPrice, Options, Quantity, Actions, ShortDescription, Description, Attributes, Breadcrumbs, GalleryContent, InfoContent, ContentYes

The slot topics for ProductAttributes, ProductGallery, and ProductOptions describe the supported Commerce boilerplate pattern. The ProductDetails (deprecated) slots section documents the legacy monolithic container only. None of these slot topics is the extension point for placing a secondary button directly under Add to Cart in the Commerce boilerplate, and you do not need to fork @dropins/storefront-pdp to get that layout. For the supported pattern, see Commerce storefront layouts (the product-details__buttons markup) and the bullets below for wiring Add to Cart and Add to Wishlist.

In the Commerce boilerplate, those controls live in your product-details block: you define empty mount elements in the HTML fragment (next to or below the quantity area), then your block script renders into them. The Commerce storefront layouts topic shows a product-details__buttons row with separate targets for Add to Cart and Add to Wishlist so you can stack or arrange them with ordinary CSS.

Use that composition pattern together with the Product Details event bus:

  • Add to Cart — Your block owns the button and wires it to cart logic and pdp/data / pdp/valid (see Notify Me CTA for the same mount pattern when stock changes the label).
  • Add to Wishlist — Initialize the Wishlist drop-in, then render WishlistToggle into a second mount point (for example, the wishlist div next to the cart div in the layout). Subscribe to pdp/data so the product you pass into WishlistToggle updates when the shopper changes configurable options.

For wishlist setup and imports, start at Wishlist quick start.

The slots for the ProductAttributes container allow you to customize its appearance and behavior.

interface ProductAttributesProps {
slots?: {
Attributes?: SlotProps<DefaultSlotContext>;
};
}

The Attributes slot allows you to customize the attributes section of the ProductAttributes container.

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductAttributes } from '@dropins/storefront-pdp/containers/ProductAttributes.js';
await provider.render(ProductAttributes, {
slots: {
Attributes: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Attributes';
ctx.appendChild(element);
}
}
})(block);

The slots for the ProductDetails container (deprecated) allow you to customize its appearance and behavior.

interface ProductDetailsProps {
slots?: {
Title?: SlotProps<DefaultSlotContext>;
SKU?: SlotProps<DefaultSlotContext>;
RegularPrice?: SlotProps<DefaultSlotContext>;
SpecialPrice?: SlotProps<DefaultSlotContext>;
Options?: SlotProps<DefaultSlotContext>;
Quantity?: SlotProps<DefaultSlotContext>;
Actions?: SlotProps<
DefaultSlotContext & {
appendButton: SlotMethod<
Omit<ButtonProps, 'icon'> & {
text?: string;
icon?: IconType;
}
>;
}
>;
ShortDescription?: SlotProps<DefaultSlotContext>;
Description?: SlotProps<DefaultSlotContext>;
Attributes?: SlotProps<DefaultSlotContext>;
Breadcrumbs?: SlotProps<
DefaultSlotContext & {
setSeparator: SlotMethod<IconType>;
appendLink: SlotMethod<
HTMLAttributes<HTMLAnchorElement> & { text?: string }
>;
appendHTMLElement: SlotMethod<HTMLElement>;
}
>;
GalleryContent?: SlotProps<DefaultSlotContext>;
InfoContent?: SlotProps<DefaultSlotContext>;
Content?: SlotProps<DefaultSlotContext>;
};
}

The Title slot allows you to customize the title section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
Title: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Title';
ctx.appendChild(element);
}
}
})(block);

The SKU slot allows you to customize the SKU section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
SKU: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom SKU';
ctx.appendChild(element);
}
}
})(block);

The RegularPrice slot allows you to customize the regular price section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
RegularPrice: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom RegularPrice';
ctx.appendChild(element);
}
}
})(block);

The SpecialPrice slot allows you to customize the special price section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
SpecialPrice: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom SpecialPrice';
ctx.appendChild(element);
}
}
})(block);

The Options slot allows you to customize the options section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
Options: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Options';
ctx.appendChild(element);
}
}
})(block);

The Quantity slot allows you to customize the quantity section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
Quantity: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Quantity';
ctx.appendChild(element);
}
}
})(block);

The Actions slot allows you to customize the actions section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
Actions: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Actions';
ctx.appendChild(element);
}
}
})(block);

The ShortDescription slot allows you to customize the short description section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
ShortDescription: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom ShortDescription';
ctx.appendChild(element);
}
}
})(block);

The Description slot allows you to customize the description section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
Description: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Description';
ctx.appendChild(element);
}
}
})(block);

The Attributes slot allows you to customize the attributes section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
Attributes: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Attributes';
ctx.appendChild(element);
}
}
})(block);

The Breadcrumbs slot allows you to customize the breadcrumbs section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
Breadcrumbs: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Breadcrumbs';
ctx.appendChild(element);
}
}
})(block);

The GalleryContent slot allows you to customize the gallery content section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
GalleryContent: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom GalleryContent';
ctx.appendChild(element);
}
}
})(block);

The InfoContent slot allows you to customize the info content section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
InfoContent: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom InfoContent';
ctx.appendChild(element);
}
}
})(block);

The Content slot allows you to customize the content section of the ProductDetails container (deprecated).

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductDetails } from '@dropins/storefront-pdp/containers/ProductDetails.js'; // (deprecated)
await provider.render(ProductDetails, {
slots: {
Content: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Content';
ctx.appendChild(element);
}
}
})(block);

The slots for the ProductGallery container allow you to customize its appearance and behavior.

interface ProductGalleryProps {
slots?: {
CarouselThumbnail?: SlotProps<
DefaultSlotContext & {
defaultImageProps: ImageProps;
mediaType?: 'image' | 'video';
previewUrl?: string;
}
>;
CarouselMainImage?: SlotProps<
DefaultSlotContext & {
defaultImageProps: ImageProps;
mediaType?: 'image' | 'video';
previewUrl?: string;
}
>;
};
}

The CarouselThumbnail slot allows you to customize the carousel thumbnail section of the ProductGallery container.

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductGallery } from '@dropins/storefront-pdp/containers/ProductGallery.js';
await provider.render(ProductGallery, {
slots: {
CarouselThumbnail: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom CarouselThumbnail';
ctx.appendChild(element);
}
}
})(block);

The CarouselMainImage slot allows you to customize the carousel main image section of the ProductGallery container.

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductGallery } from '@dropins/storefront-pdp/containers/ProductGallery.js';
await provider.render(ProductGallery, {
slots: {
CarouselMainImage: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom CarouselMainImage';
ctx.appendChild(element);
}
}
})(block);

The slots for the ProductOptions container allow you to customize its appearance and behavior.

interface ProductOptionsProps {
slots?: {
Swatches?: SlotProps<{ data: ProductModel | null; optionsUIDs: string[] }>;
SwatchImage?: SlotProps<{
data: ProductModel | null;
optionsUIDs: string[];
imageSwatchContext: ImageNodeRenderProps['imageSwatchContext'];
defaultImageProps: ImageProps;
}>;
};
}

The Swatches slot allows you to customize the swatches section of the ProductOptions container.

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductOptions } from '@dropins/storefront-pdp/containers/ProductOptions.js';
await provider.render(ProductOptions, {
slots: {
Swatches: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom Swatches';
ctx.appendChild(element);
}
}
})(block);

The SwatchImage slot allows you to customize the swatch image section of the ProductOptions container.

import { render as provider } from '@dropins/storefront-pdp/render.js';
import { ProductOptions } from '@dropins/storefront-pdp/containers/ProductOptions.js';
await provider.render(ProductOptions, {
slots: {
SwatchImage: (ctx) => {
// Your custom implementation
const element = document.createElement('div');
element.innerText = 'Custom SwatchImage';
ctx.appendChild(element);
}
}
})(block);