Skip to content

PDP slots

The product details page (PDP) drop-in component 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 component 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 component 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.