Skip to content

PDP Slots

The Product Details dropin provides slots for nearly every part of its UI. The default UI controls for these PDP slots are described below.

PDP slots
PDP slots
  1. Title: Uses HTML elements to display the product’s title.
  2. SKU: Uses HTML elements to display the product’s SKU (Stock Keeping Unit).
  3. RegularPrice: Uses our Price control to display the regular price of the product.
  4. SpecialPrice: Uses our Price control to highlight a special or discounted price.
  5. Options: Uses our TextSwatch, ColorSwatch, or ImageSwatch to display product options like sizes, colors, or images.
  6. Quantity: Uses our Incrementer control to display the quantity of the product being viewed or purchased.
  7. Actions: Typically uses our Button controls and the onClick handler to add products to the Cart or wishlist.
  8. ShortDescription: Uses HTML elements to display a brief description or summary of the product.
  9. Description: Uses HTML elements to display the main description area for detailed information about the product.
  10. Attributes: Uses HTML elements to display additional product attributes like weight, dimensions, or material.

PDP SlotProps

The slots for Product Details are defined in the ProductDetailsProps interface. Each slot comes with a set of primitive functions and may be extended with custom functions, such as appendButton.

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>;
Details?: 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>;
};

Example customizations

Here are some examples of how you can customize the Product Details dropin using the slots:

Title

Adding a decoration to the product title, as well as a ratings element.

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
Title: (ctx) => {
// title decoration
const tagline = document.createElement('div');
tagline.classList.add('title-decoration');
tagline.innerHTML = 'WKND Essentials';
ctx.prependSibling(tagline);
const rating = document.createElement('div');
rating.classList.add('ratings');
rating.innerHTML = '⭐️⭐️⭐️⭐️⭐️';
ctx.appendSibling(rating);
},
},
});

SKU

Append some copy with strikethrough to the SKU when out of stock.

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
SKU: (ctx) => {
const stockStatus = document.createElement('div');
ctx.onChange((next) => {
if (next.data.inStock) {
stockStatus.style.textDecoration = 'none';
stockStatus.innerText = 'In Stock';
} else {
stockStatus.style.textDecoration = 'line-through';
stockStatus.innerText = 'Out of Stock';
}
});
ctx.appendSibling(stockStatus);
},
},
});

Regular Price

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
// Title: (ctx) => {},
// SKU: (ctx) => {},
RegularPrice: (ctx) => {
const regularPrice = document.createElement('div');
// add good example
},
},
});

Special Price

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
SpecialPrice: (ctx) => {
const specialPrice = document.createElement('div');
// add good example
},
},
});

Options

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
Options: (ctx) => {
console.log('Options', ctx.values);
const size = ctx.getSlotElement('product-swatch--size');
if (size) {
const sizesLink = document.createElement('a');
sizesLink.classList.add('sizes-link');
sizesLink.innerHTML = 'Size Chart';
sizesLink.setAttribute('href', '#sizes');
size.appendChild(sizesLink);
}
},
},
});

Quantity

Adding some translated copy to the Quantity field.

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
Quantity: (ctx) => {
// quantity decoration
const quantity = document.createElement('div');
quantity.classList.add('quantity-decoration');
quantity.innerText = 'Quantity';
ctx.prependChild(quantity);
const promo = document.createElement('div');
promo.classList.add('promo');
promo.innerText = 'Buy 2, Get 1 Free';
ctx.appendChild(promo);
ctx.onChange((next) => {
quantity.innerText = `${next.dictionary.Custom.quantityLabel}`;
promo.innerText = `${next.dictionary.Custom.promoLabel}:`;
});
},
},
});

Actions

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
Actions: (ctx) => {
// actions decoration
const actions = document.createElement('div');
actions.classList.add('actions-decoration');
actions.innerHTML = 'Actions';
ctx.prependChild(actions);
const addToCart = ctx.appendButton({
text: 'Add to Cart',
icon: 'cart',
onClick: () => {
console.log('Add to Cart clicked');
},
});
const addToWishlist = ctx.appendButton({
text: 'Add to Wishlist',
icon: 'heart',
onClick: () => {
console.log('Add to Wishlist clicked');
},
});
const share = ctx.appendButton({
text: 'Share',
icon: 'share',
onClick: () => {
console.log('Share clicked');
},
});
},
},
});

Short Description

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
ShortDescription: (ctx) => {
const shortDescription = document.createElement('div');
// add good example
},
},
});

Description

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
Description: (ctx) => {
const description = document.createElement('div');
// add good example
},
},
});

Attributes

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
Attributes: (ctx) => {
const attributes = document.createElement('div');
// add good example
},
},
});

GalleryContent

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
GalleryContent: (ctx) => {
const galleryContent = document.createElement('div');
// add good example
},
},
});

InfoContent

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
InfoContent: (ctx) => {
const infoContent = document.createElement('div');
// add good example
},
},
});

Content

return productRenderer.render(ProductDetails, {
sku: getSkuFromUrl(),
slots: {
Content: (ctx) => {
const productContent = document.createElement('div');
// add good example
},
},
});

Summary

The Product Details dropin provides slots for nearly every part of its UI, allowing you to customize every detail to create a unique and branded experience for your customers.