Cart slots
Learn about the slots provided in the Cart drop-in component.
Extending drop-in components describes default properties available to all slots.
CartSummaryList slots
The slots for the CartSummaryList
container allow you to customize the appearance of the cart summary list.
interface CartSummaryListProps
slots?: { Heading?: SlotProps; EmptyCart?: SlotProps; Thumbnail?: SlotProps; Footer?: SlotProps; ProductAttributes?: SlotProps; CartSummaryFooter?: SlotProps;};
Heading slot
The Heading
slot allows you to add content to the top of the CartSummaryList
container.
provider.render(CartSummaryList, { slots: { Heading: (ctx) => { // Runs on mount const heading = document.createElement('h2'); heading.innerText = 'Cart List'; ctx.appendChild(heading); }, },})($list),
EmptyCart slot
The EmptyCart
slot allows you to add content to the CartSummaryList
container when the cart is empty.
provider.render(CartSummaryList, { slots: { EmptyCart: (ctx) => { // Runs on mount const emptyCart = document.createElement('div'); emptyCart.innerText = 'Your cart is empty'; ctx.appendChild(emptyCart); }, },})($list),
Thumbnail slot
Define a callback function in the Thumbnail
slot of the CartSummaryList
container to modify or replace the thumbnail section for each item in the cart.
The context object passed to the callback function includes an item
property that contains the item data with the following type:
export interface Item { taxedPrice: { value: number; currency: string; }; rowTotal: { value: number; currency: string; }; rowTotalIncludingTax: { value: number; currency: string; }; itemType: string; uid: string; url: { urlKey: string; categories: string[]; }; quantity: number; sku: string; name: string; image: { src: string; alt: string; }; links?: { count: number; result: string; }; price: { value: number; currency: string; }; total: { value: number; currency: string; }; discountedTotal?: { value: number; currency: string; }; discount?: { value: number; currency: string; }; regularPrice: { value: number; currency: string; }; discounted: boolean; bundleOptions?: { [key: string]: any }; selectedOptions?: { [key: string]: any }; customizableOptions?: { [key: string]: any }; message?: string; recipient?: string; recipientEmail?: string; sender?: string; senderEmail?: string; lowInventory?: boolean; insufficientQuantity?: boolean; onlyXLeftInStock?: number | null; outOfStock?: boolean; notAvailableMessage?: string; stockLevel?: string; productAttributes?: Array<{ code: string; value?: string; selected_options?: { value: string; label: string; }[];}>;}
Example extension
The following example demonstrates how to extend the Thumbnail
slot.
return provider.render(CartSummaryList, { hideHeading: hideHeading === 'true', routeProduct: (product) => `/products/${product.url.urlKey}/${product.sku}`, routeEmptyCartCTA: startShoppingURL ? () => startShoppingURL : undefined, maxItems: parseInt(maxItems, 10) || undefined, attributesToHide: hideAttributes.split(',').map((attr) => attr.trim().toLowerCase()), enableUpdateItemQuantity: enableUpdateItemQuantity === 'true', enableRemoveItem: enableRemoveItem === 'true', slots: { Thumbnail: (ctx) => { const { item } = ctx;
// Create a link to save the item for later const saveForLaterLink = document.createElement('a'); saveForLaterLink.href = '#'; saveForLaterLink.addEventListener('click', (e) => { e.preventDefault(); console.log(`Saving ${item.name}(${item.sku}) for later`); // TODO: Implement save for later functionality }); saveForLaterLink.innerText = 'Save for later';
// Create a separator const separator = document.createElement('span'); separator.innerText = ' | ';
// Create a link to remove the item from the cart const removeLink = document.createElement('a'); removeLink.href = '#'; removeLink.addEventListener('click', (e) => { e.preventDefault(); console.log(`Removing ${item.name}(${item.sku}) from cart`); // TODO: Implement remove item functionality }); removeLink.innerText = 'Remove';
// Create a container to hold the links const container = document.createElement('div'); container.innerHTML = '<div class="cart-summary__thumbnail"/>';
// Style the container container.style.font = 'var(--type-details-caption-2-font)' container.style.display = 'flex'; container.style.justifyContent = 'space-between';
// Append the links to the container container.appendChild(saveForLaterLink); container.appendChild(separator); container.appendChild(removeLink);
// Append the container as a child to the existing thumbnail content ctx.appendChild(container) } } })(block);
Footer slot
The Footer
slot allows you to add content to the bottom of the CartSummaryList
container.
The following example demonstrates how to extend the Footer
slot by adding a promotional cart rule to each product in the cart.
Footer: (ctx) => { // Runs on mount const wrapper = document.createElement('div'); ctx.appendChild(wrapper);
// Append Product Promotions on every update ctx.onChange((next) => { wrapper.innerHTML = '';
next.item?.discount?.label?.forEach((label) => { const discount = document.createElement('div'); discount.style.color = '#3d3d3d'; discount.innerText = label; wrapper.appendChild(discount); }); });},
ProductAttributes slot
The ProductAttributes
slot allows you to add custom content to the CartSummaryList
container.
The following example demonstrates how to add the Fashion Material and Fashion Style product attributes to each product in the cart.
return provider.render(CartSummaryList, { enableRemoveItem: true, enableUpdateItemQuantity: true, routeProduct: (item) => { return `${item.url.categories.join('/')}/${item.url.urlKey}`; }, routeEmptyCartCTA: () => '#empty-cart', slots: { ProductAttributes: (ctx) => { // Prepend Product Attributes const ProductAttributes = ctx.item?.productAttributes;
ProductAttributes?.forEach((attr) => { if(attr.code === "Fashion Material" || attr.code === "Fashion Style") { if(attr.selected_options) { const selectedOptions = attr.selected_options .filter((option) => option.label.trim() !== '') .map((option) => option.label) .join(', ');
if(selectedOptions) { const productAttribute = document.createElement('div'); productAttribute.innerText = `${attr.code}: ${selectedOptions}`; ctx.appendChild(productAttribute); } } else if (attr.value) { const productAttribute = document.createElement('div'); productAttribute.innerText = `${attr.code}: ${attr.value}`; ctx.appendChild(productAttribute); } } }) }, }, })(productList);
CartSummaryFooter slot
The CartSummaryFooter
slot allows you to add content to the bottom of the CartSummaryList
container.
provider.render(CartSummaryList, { slots: { CartSummaryFooter: (ctx) => { const cartSummaryFooter = document.createElement('div'); cartSummaryFooter.innerText = 'Cart summary footer'; ctx.appendChild(cartSummaryFooter); }, },})($list),
OrderSummary slots
The OrderSummaryProps
interface defines two slots for customizing the appearance of the order summary.
interface OrderSummaryProps
slots?: { EstimateShipping?: SlotProps; Coupons?: SlotProps;};
EstimateShipping slot
The EstimateShipping
slot allows you to add estimated shipping information to the OrderSummary
container.
The following example demonstrates how to add the Estimate Shipping layout to the OrderSummary container.
return provider.render(OrderSummary, { routeCheckout: () => '#checkout',
errors: ctx.hasErrors,
slots: { EstimateShipping: (ctx) => { const estimateShippingForm = document.createElement('div');
provider.render(EstimateShipping)(estimateShippingForm);
ctx.appendChild(estimateShippingForm); } }, })(orderSummary);
Coupons slot
The Coupons slot allows you to add the Coupons layout to the OrderSummary
container.
The following example demonstrates how to enable coupons to the OrderSummary
container.
return provider.render(OrderSummary, { routeCheckout: () => '#checkout',
errors: ctx.hasErrors,
slots: { Coupons: (ctx) => { const coupons = document.createElement('div');
provider.render(Coupons)(coupons);
ctx.appendChild(coupons); } }, })(orderSummary);
MiniCart slot
The MiniCartProps
interface defines slots for customizing the appearance of the mini cart.
interface MiniCartProps
slots?: { ProductList?: SlotProps; ProductListFooter?: SlotProps; PreCheckoutSection?: SlotProps;};
ProductListFooter slot
The ProductListFooter slot allows you to add content after the product list and before the subtotal section of the MiniCart
container.
The following example demonstrates how to extend the ProductListFooter
by adding the store return policy.
return provider.render(MiniCart, { routeEmptyCartCTA: () => '#empty-cart', routeCart: () => '#cart', routeCheckout: () => '#checkout', slots: { ProductListFooter: (ctx) => { const productListFooter = document.createElement('div'); ctx.appendChild(productListFooter);
ctx.onChange((next) => { // Clear the existing content productListFooter.innerHTML = '';
if (Object.keys(next.data.items).length === 0) { return; }
const shadowWrapper = document.createElement('div'); shadowWrapper.style.backgroundColor = '#EFF5EF'; shadowWrapper.style.borderRadius = '5px';
// Create the content div const contentDiv = document.createElement('div'); contentDiv.innerHTML = "<p style='line-height: 1.5;'>Enjoy hassle-free shopping with our 30-day return policy!</p>"; contentDiv.style.display = 'flex'; contentDiv.style.flexDirection = 'column'; contentDiv.style.padding = '12px';
// Append the content div to the shadow wrapper shadowWrapper.appendChild(contentDiv);
productListFooter.appendChild(shadowWrapper); }); }, }, })(orderSummary);
PreCheckoutSection slot
The PreCheckoutSection slot allows you to add content after the the subtotal section and before the Call to Action buttons of the MiniCart
container.
The following example demonstrates how to extend the PreCheckoutSection
by adding the loyalty program callouts.
return provider.render(MiniCart, { routeEmptyCartCTA: () => '#empty-cart', routeCart: () => '#cart', routeCheckout: () => '#checkout', slots: { PreCheckoutSection: (ctx) => { const preCheckoutSection = document.createElement('div'); ctx.appendChild(preCheckoutSection);
ctx.onChange((next) => { // Clear the existing content preCheckoutSection.innerHTML = '';
if (Object.keys(next.data.items).length === 0) { return; }
// Create a wrapper div for the shadow background const shadowWrapper = document.createElement('div'); shadowWrapper.style.backgroundColor = '#EEEFFB'; shadowWrapper.style.borderRadius = '5px';
// Create the content div const contentDiv = document.createElement('div'); contentDiv.innerHTML = "<p style='line-height: 1.5;'>Earn rewards every time you shop! Sign up for our free loyalty program today and start earning points on this purchase.</p>"; contentDiv.style.display = 'flex'; contentDiv.style.flexDirection = 'column'; contentDiv.style.padding = '12px';
// Append the content div to the shadow wrapper shadowWrapper.appendChild(contentDiv);
// Append the shadow wrapper to the preCheckoutSection div preCheckoutSection.appendChild(shadowWrapper); }); }, }, })(orderSummary);