Skip to content

Cart Slots

The Cart drop-in exposes 49 slots in 6 containers for customizing specific UI sections. Use slots to replace or extend container components. For default properties available to all slots, see Extending drop-in components.

Version: 1.5.1
ContainerSlots
CartSummaryGridThumbnail
CartSummaryListHeading, EmptyCart, Footer, Thumbnail, ProductAttributes, CartSummaryFooter, CartItem, UndoBanner, ItemTitle, ItemPrice, ItemQuantity, ItemTotal, ItemSku, ItemRemoveAction
CartSummaryTableItem, Price, Quantity, Subtotal, Thumbnail, ProductTitle, Sku, Configurations, ItemAlert, ItemWarning, Actions, UndoBanner, EmptyCart
GiftOptionsSwatchImage
MiniCartProductList, ProductListFooter, PreCheckoutSection, Thumbnail, Heading, EmptyCart, Footer, ProductAttributes, CartSummaryFooter, CartItem, UndoBanner, ItemTitle, ItemPrice, ItemQuantity, ItemTotal, ItemSku, ItemRemoveAction
OrderSummaryEstimateShipping, Coupons, GiftCards

CartSummaryGrid slots

interface CartSummaryGridProps
slots?: {
Thumbnail?: SlotProps<{
item: CartModel['items'][number],
defaultImageProps: ImageProps
}>;
};

CartSummaryList slots

interface CartSummaryListProps
slots?: {
Heading?: SlotProps;
EmptyCart?: SlotProps;
Footer?: SlotProps;
Thumbnail?: SlotProps<{
item: CartModel['items'][number];
defaultImageProps: ImageProps;
}>;
ProductAttributes?: SlotProps;
CartSummaryFooter?: SlotProps;
CartItem?: SlotProps;
UndoBanner?: SlotProps<{
item: CartModel['items'][0];
loading: boolean;
error?: string;
onUndo: () => void;
onDismiss: () => void;
}>;
ItemTitle?: SlotProps<{ item: CartModel['items'][number] }>;
ItemPrice?: SlotProps<{ item: CartModel['items'][number] }>;
ItemQuantity?: SlotProps<{
item: CartModel['items'][number];
enableUpdateItemQuantity: boolean;
handleItemQuantityUpdate: (
item: CartModel['items'][number],
quantity: number
) => void;
itemsLoading: Set<string>;
handleItemsError: (uid: string, message?: string) => void;
handleItemsLoading: (uid: string, state: boolean) => void;
onItemUpdate?: ({ item }: { item: CartModel['items'][number] }) => void;
}>;
ItemTotal?: SlotProps<{ item: CartModel['items'][number] }>;
ItemSku?: SlotProps<{ item: CartModel['items'][number] }>;
ItemRemoveAction?: SlotProps<{
item: CartModel['items'][number];
enableRemoveItem: boolean;
handleItemQuantityUpdate: (
item: CartModel['items'][number],
quantity: number
) => void;
handleItemsError: (uid: string, message?: string) => void;
handleItemsLoading: (uid: string, state: boolean) => void;
onItemUpdate?: ({ item }: { item: CartModel['items'][number] }) => void;
itemsLoading: Set<string>;
}>;
};

Heading example

This example from the Commerce Checkout block shows how to customize the Heading slot:

import { render as provider } from '@dropins/storefront-cart/render.js';
import CartSummaryList from '@dropins/storefront-cart/containers/CartSummaryList.js';
import { rootLink } from '../../scripts/commerce.js';
provider.render(CartSummaryList, {
slots: {
Heading: (headingCtx) => {
const title = 'Your Cart ({count})';
const cartSummaryListHeading = document.createElement('div');
cartSummaryListHeading.classList.add('cart-summary-list__heading');
const cartSummaryListHeadingText = document.createElement('div');
cartSummaryListHeadingText.classList.add(
'cart-summary-list__heading-text',
);
cartSummaryListHeadingText.innerText = title.replace(
'({count})',
headingCtx.count ? `(${headingCtx.count})` : '',
);
const editCartLink = document.createElement('a');
editCartLink.classList.add('cart-summary-list__edit');
editCartLink.href = rootLink('/cart');
editCartLink.rel = 'noreferrer';
editCartLink.innerText = 'Edit';
cartSummaryListHeading.appendChild(cartSummaryListHeadingText);
cartSummaryListHeading.appendChild(editCartLink);
headingCtx.appendChild(cartSummaryListHeading);
headingCtx.onChange((nextHeadingCtx) => {
cartSummaryListHeadingText.innerText = title.replace(
'({count})',
nextHeadingCtx.count ? `(${nextHeadingCtx.count})` : '',
);
});
}
}
})(document.querySelector('.cart-summary-list'));

This example from the Commerce Cart block shows how to customize the Footer slot:

import { render as provider } from '@dropins/storefront-cart/render.js';
import CartSummaryList from '@dropins/storefront-cart/containers/CartSummaryList.js';
import { Button, Icon, provider as UI } from '@dropins/tools/components.js';
import { h } from '@dropins/tools/preact.js';
import { WishlistToggle } from '@dropins/storefront-wishlist/containers/WishlistToggle.js';
import { render as wishlistRender } from '@dropins/storefront-wishlist/render.js';
import GiftOptions from '@dropins/storefront-cart/containers/GiftOptions.js';
// Note: `placeholders` should be defined in your block context (typically from `fetchPlaceholders()`)
// Note: `enableUpdatingProduct` should be defined in your block context
// Note: `handleEditButtonClick` should be defined in your block context
// Note: `swatchImageSlot` should be defined in your block context (typically imported from a local utils file)
provider.render(CartSummaryList, {
slots: {
Footer: (ctx) => {
// Edit Link
if (ctx.item?.itemType === 'ConfigurableCartItem' && enableUpdatingProduct === 'true') {
const editLink = document.createElement('div');
editLink.className = 'cart-item-edit-link';
UI.render(Button, {
children: placeholders?.Global?.CartEditButton,
variant: 'tertiary',
size: 'medium',
icon: h(Icon, { source: 'Edit' }),
onClick: () => handleEditButtonClick(ctx.item),
})(editLink);
ctx.appendChild(editLink);
}
// Wishlist Button (if product is not configurable)
const $wishlistToggle = document.createElement('div');
$wishlistToggle.classList.add('cart__action--wishlist-toggle');
wishlistRender.render(WishlistToggle, {
product: ctx.item,
size: 'medium',
labelToWishlist: placeholders?.Global?.CartMoveToWishlist,
labelWishlisted: placeholders?.Global?.CartRemoveFromWishlist,
removeProdFromCart: Cart.updateProductsFromCart,
})($wishlistToggle);
ctx.appendChild($wishlistToggle);
// Gift Options
const giftOptions = document.createElement('div');
provider.render(GiftOptions, {
item: ctx.item,
view: 'product',
dataSource: 'cart',
handleItemsLoading: ctx.handleItemsLoading,
handleItemsError: ctx.handleItemsError,
onItemUpdate: ctx.onItemUpdate,
slots: {
SwatchImage: swatchImageSlot,
},
})(giftOptions);
ctx.appendChild(giftOptions);
}
}
})(document.querySelector('.cart-summary-list'));

Thumbnail example

This example from the Commerce Cart block shows how to customize the Thumbnail slot:

import { render as provider } from '@dropins/storefront-cart/render.js';
import CartSummaryList from '@dropins/storefront-cart/containers/CartSummaryList.js';
import { tryRenderAemAssetsImage } from '@dropins/tools/lib/aem/assets.js';
import { getProductLink } from '../../scripts/commerce.js';
const createProductLink = (item) => getProductLink(item.urlKey, item.sku);
provider.render(CartSummaryList, {
slots: {
Thumbnail: (ctx) => {
const { item, defaultImageProps } = ctx;
const anchorWrapper = document.createElement('a');
anchorWrapper.href = createProductLink(item);
tryRenderAemAssetsImage(ctx, {
alias: item.sku,
imageProps: defaultImageProps,
wrapper: anchorWrapper,
params: {
width: defaultImageProps.width,
height: defaultImageProps.height,
},
});
}
}
})(document.querySelector('.cart-summary-list'));

CartSummaryTable slots

interface CartSummaryTableProps
slots?: {
Item?: SlotProps<{ item: CartModel['items'][number] }>;
Price?: SlotProps<{ item: CartModel['items'][number] }>;
Quantity?: SlotProps<{
item: CartModel['items'][number];
isUpdating: boolean;
quantityInputValue: number;
handleInputChange: (e: Event) => void;
itemUpdateErrors: Map<string, string>;
}>;
Subtotal?: SlotProps<{ item: CartModel['items'][number] }>;
Thumbnail?: SlotProps<{
item: CartModel['items'][number];
defaultImageProps: ImageProps;
index: number;
}>;
ProductTitle?: SlotProps<{ item: CartModel['items'][number] }>;
Sku?: SlotProps<{ item: CartModel['items'][number] }>;
Configurations?: SlotProps<{ item: CartModel['items'][number] }>;
ItemAlert?: SlotProps<{ item: CartModel['items'][number] }>;
ItemWarning?: SlotProps<{ item: CartModel['items'][number] }>;
Actions?: SlotProps<{
item: CartModel['items'][number];
itemsUpdating: Map<string, { isUpdating: boolean; updatedValue: number }>;
setItemUpdating: (uid: string, state: boolean) => void;
setItemUpdateError: (uid: string, error: string) => void;
}>;
UndoBanner?: SlotProps<{
item: CartModel['items'][number];
loading: boolean;
error?: string;
onUndo: () => void;
onDismiss: () => void;
}>;
EmptyCart?: SlotProps;
};

GiftOptions slots

interface GiftOptionsProps
slots?: {
SwatchImage?: SlotProps<{
item: Item | ProductGiftOptionsConfig
imageSwatchContext: ImageNodeRenderProps['imageSwatchContext']
defaultImageProps: ImageProps
}>;
};

SwatchImage example

This example from the Commerce Order Product List block shows how to customize the SwatchImage slot:

import { render as provider } from '@dropins/storefront-cart/render.js';
import GiftOptions from '@dropins/storefront-cart/containers/GiftOptions.js';
import { tryRenderAemAssetsImage } from '@dropins/tools/lib/aem/assets.js';
provider.render(GiftOptions, {
slots: {
SwatchImage: (swatchCtx) => {
const { defaultImageProps, imageSwatchContext } = swatchCtx;
tryRenderAemAssetsImage(swatchCtx, {
alias: imageSwatchContext.label,
imageProps: defaultImageProps,
wrapper: document.createElement('span'),
params: {
width: defaultImageProps.width,
height: defaultImageProps.height,
},
});
}
}
})(document.querySelector('.gift-options'));

MiniCart slots

interface MiniCartProps
slots?: {
ProductList?: SlotProps;
ProductListFooter?: SlotProps;
PreCheckoutSection?: SlotProps;
Thumbnail?: SlotProps<{
item: CartModel['items'][number];
defaultImageProps: ImageProps;
}>;
Heading?: SlotProps;
EmptyCart?: SlotProps;
Footer?: SlotProps;
ProductAttributes?: SlotProps;
CartSummaryFooter?: SlotProps;
CartItem?: SlotProps;
UndoBanner?: SlotProps<{
item: CartModel['items'][0];
loading: boolean;
error?: string;
onUndo: () => void;
onDismiss: () => void;
}>;
ItemTitle?: SlotProps<{ item: CartModel['items'][number] }>;
ItemPrice?: SlotProps<{ item: CartModel['items'][number] }>;
ItemQuantity?: SlotProps<{
item: CartModel['items'][number];
enableUpdateItemQuantity: boolean;
handleItemQuantityUpdate: (
item: CartModel['items'][number],
quantity: number
) => void;
itemsLoading: Set<string>;
handleItemsError: (uid: string, message?: string) => void;
handleItemsLoading: (uid: string, state: boolean) => void;
onItemUpdate?: ({ item }: { item: CartModel['items'][number] }) => void;
}>;
ItemTotal?: SlotProps<{ item: CartModel['items'][number] }>;
ItemSku?: SlotProps<{ item: CartModel['items'][number] }>;
ItemRemoveAction?: SlotProps<{
item: CartModel['items'][number];
enableRemoveItem: boolean;
handleItemQuantityUpdate: (
item: CartModel['items'][number],
quantity: number
) => void;
handleItemsError: (uid: string, message?: string) => void;
handleItemsLoading: (uid: string, state: boolean) => void;
onItemUpdate?: ({ item }: { item: CartModel['items'][number] }) => void;
itemsLoading: Set<string>;
}>;
};

Thumbnail example

This example from the Commerce Mini Cart block shows how to customize the Thumbnail slot:

import { render as provider } from '@dropins/storefront-cart/render.js';
import MiniCart from '@dropins/storefront-cart/containers/MiniCart.js';
import { Button, Icon, provider as UI } from '@dropins/tools/components.js';
import { h } from '@dropins/tools/preact.js';
import { tryRenderAemAssetsImage } from '@dropins/tools/lib/aem/assets.js';
import { getProductLink } from '../../scripts/commerce.js';
const createProductLink = (item) => getProductLink(item.urlKey, item.sku);
// Note: `placeholders` should be defined in your block context (typically from `fetchPlaceholders()`)
// Note: `enableUpdatingProduct` should be defined in your block context
// Note: `handleEditButtonClick` should be defined in your block context
provider.render(MiniCart, {
slots: {
Thumbnail: (ctx) => {
const { item, defaultImageProps } = ctx;
const anchorWrapper = document.createElement('a');
anchorWrapper.href = createProductLink(item);
tryRenderAemAssetsImage(ctx, {
alias: item.sku,
imageProps: defaultImageProps,
wrapper: anchorWrapper,
params: {
width: defaultImageProps.width,
height: defaultImageProps.height,
},
});
if (item?.itemType === 'ConfigurableCartItem' && enableUpdatingProduct === 'true') {
const editLinkContainer = document.createElement('div');
editLinkContainer.className = 'cart-item-edit-container';
const editLink = document.createElement('div');
editLink.className = 'cart-item-edit-link';
UI.render(Button, {
children: placeholders?.Global?.CartEditButton,
variant: 'tertiary',
size: 'medium',
icon: h(Icon, { source: 'Edit' }),
onClick: () => handleEditButtonClick(item),
})(editLink);
editLinkContainer.appendChild(editLink);
ctx.appendChild(editLinkContainer);
}
}
}
})(document.querySelector('.mini-cart'));

OrderSummary slots

interface OrderSummaryProps
slots?: {
EstimateShipping?: SlotProps;
Coupons?: SlotProps;
GiftCards?: SlotProps;
};

EstimateShipping example

This example from the Commerce Cart block shows how to customize the EstimateShipping slot:

import { render as provider } from '@dropins/storefront-cart/render.js';
import OrderSummary from '@dropins/storefront-cart/containers/OrderSummary.js';
provider.render(OrderSummary, {
slots: {
EstimateShipping: async (ctx) => {
if (enableEstimateShipping === 'true') {
const wrapper = document.createElement('div');
await provider.render(EstimateShipping, {})(wrapper);
ctx.replaceWith(wrapper);
}
}
}
})(document.querySelector('.order-summary'));

Coupons example

This example from the Commerce Cart block shows how to customize the Coupons slot:

import { render as provider } from '@dropins/storefront-cart/render.js';
import OrderSummary from '@dropins/storefront-cart/containers/OrderSummary.js';
provider.render(OrderSummary, {
slots: {
Coupons: (ctx) => {
const coupons = document.createElement('div');
provider.render(Coupons)(coupons);
ctx.appendChild(coupons);
}
}
})(document.querySelector('.order-summary'));

GiftCards example

This example from the Commerce Cart block shows how to customize the GiftCards slot:

import { render as provider } from '@dropins/storefront-cart/render.js';
import OrderSummary from '@dropins/storefront-cart/containers/OrderSummary.js';
provider.render(OrderSummary, {
slots: {
GiftCards: (ctx) => {
const giftCards = document.createElement('div');
provider.render(GiftCards)(giftCards);
ctx.appendChild(giftCards);
}
}
})(document.querySelector('.order-summary'));