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.
| Container | Slots |
|---|---|
CartSummaryGrid | Thumbnail |
CartSummaryList | Heading, EmptyCart, Footer, Thumbnail, ProductAttributes, CartSummaryFooter, CartItem, UndoBanner, ItemTitle, ItemPrice, ItemQuantity, ItemTotal, ItemSku, ItemRemoveAction |
CartSummaryTable | Item, Price, Quantity, Subtotal, Thumbnail, ProductTitle, Sku, Configurations, ItemAlert, ItemWarning, Actions, UndoBanner, EmptyCart |
GiftOptions | SwatchImage |
MiniCart | ProductList, ProductListFooter, PreCheckoutSection, Thumbnail, Heading, EmptyCart, Footer, ProductAttributes, CartSummaryFooter, CartItem, UndoBanner, ItemTitle, ItemPrice, ItemQuantity, ItemTotal, ItemSku, ItemRemoveAction |
OrderSummary | EstimateShipping, 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'));Footer example
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'));