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.
| Container | Slots | Deprecated |
|---|---|---|
ProductAttributes | Attributes | No |
ProductGallery | CarouselThumbnail, CarouselMainImage | No |
ProductOptions | Swatches, SwatchImage | No |
ProductDetails container (deprecated) | Title, SKU, RegularPrice, SpecialPrice, Options, Quantity, Actions, ShortDescription, Description, Attributes, Breadcrumbs, GalleryContent, InfoContent, Content | Yes |
Add to Cart and Add to Wishlist
Section titled “Add to Cart and Add to Wishlist”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
WishlistToggleinto a second mount point (for example, the wishlistdivnext to the cartdivin the layout). Subscribe topdp/dataso theproductyou pass intoWishlistToggleupdates when the shopper changes configurable options.
For wishlist setup and imports, start at Wishlist quick start.
ProductAttributes slots
Section titled “ProductAttributes slots”The slots for the ProductAttributes container allow you to customize its appearance and behavior.
interface ProductAttributesProps { slots?: { Attributes?: SlotProps<DefaultSlotContext>; };}Attributes slot
Section titled “Attributes slot”The Attributes slot allows you to customize the attributes section of the ProductAttributes container.
Example
Section titled “Example”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);ProductDetails (deprecated) slots
Section titled “ProductDetails (deprecated) slots”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>; };}Title slot
Section titled “Title slot”The Title slot allows you to customize the title section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);SKU slot
Section titled “SKU slot”The SKU slot allows you to customize the SKU section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);RegularPrice slot
Section titled “RegularPrice slot”The RegularPrice slot allows you to customize the regular price section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);SpecialPrice slot
Section titled “SpecialPrice slot”The SpecialPrice slot allows you to customize the special price section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);Options slot
Section titled “Options slot”The Options slot allows you to customize the options section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);Quantity slot
Section titled “Quantity slot”The Quantity slot allows you to customize the quantity section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);Actions slot
Section titled “Actions slot”The Actions slot allows you to customize the actions section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);ShortDescription slot
Section titled “ShortDescription slot”The ShortDescription slot allows you to customize the short description section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);Description slot
Section titled “Description slot”The Description slot allows you to customize the description section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);Attributes slot
Section titled “Attributes slot”The Attributes slot allows you to customize the attributes section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);Breadcrumbs slot
Section titled “Breadcrumbs slot”The Breadcrumbs slot allows you to customize the breadcrumbs section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);GalleryContent slot
Section titled “GalleryContent slot”The GalleryContent slot allows you to customize the gallery content section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);InfoContent slot
Section titled “InfoContent slot”The InfoContent slot allows you to customize the info content section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);Content slot
Section titled “Content slot”The Content slot allows you to customize the content section of the ProductDetails container (deprecated).
Example
Section titled “Example”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);ProductGallery slots
Section titled “ProductGallery slots”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; } >; };}CarouselThumbnail slot
Section titled “CarouselThumbnail slot”The CarouselThumbnail slot allows you to customize the carousel thumbnail section of the ProductGallery container.
Example
Section titled “Example”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);CarouselMainImage slot
Section titled “CarouselMainImage slot”The CarouselMainImage slot allows you to customize the carousel main image section of the ProductGallery container.
Example
Section titled “Example”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);ProductOptions slots
Section titled “ProductOptions slots”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; }>; };}Swatches slot
Section titled “Swatches slot”The Swatches slot allows you to customize the swatches section of the ProductOptions container.
Example
Section titled “Example”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);SwatchImage slot
Section titled “SwatchImage slot”The SwatchImage slot allows you to customize the swatch image section of the ProductOptions container.
Example
Section titled “Example”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);