Customize order summary lines
The Cart drop-in’s OrderSummary container renders a fixed set of lines by default, such as subtotal, discounts, and tax. This tutorial shows you how to customize those lines: reorder, remove, or add your own, using the updateLineItems prop.
What you’ll edit or create
Section titled “What you’ll edit or create”- Edit the
OrderSummarycontainer - Edit the
updateLineItemsprop - Edit the
OrderSummaryLinecontainer
What you’ll build
Section titled “What you’ll build”By the end of this tutorial, you’ll have:
- Order summary lines customized through the
updateLineItemsprop on theOrderSummarycontainer — reordering, removing, or adding lines like the fixed product tax (FPT) example. - Subtotal and tax lines grouped into a collapsible section using the Storefront SDK’s Accordion component.
- A new order summary line rendered with the
OrderSummaryLinecontainer, showing a custom label and price.
Customize the lines of the Order Summary to meet your needs
Section titled “Customize the lines of the Order Summary to meet your needs”This customization is possible thanks to the attribute updateLineItems from the OrderSummary container. This attribute allows you to modify the order summary lines before they are rendered.
export const OrderSummary: Container<OrderSummaryProps, CartModel | null> = ({ ... updateLineItems = (lineItems) => lineItems, ...});It doesn’t matter if you want to customize the existing order summary lines, add new ones, or skip some of them.
The OrderSummary container passes the updateLineItems to the OrderSummary component, which performs the appropriate actions.
updateLineItems is an optional function that receives the line items as an argument and returns the updated line items. In both cases, lineItems are an array of OrderSummaryLineItem object.
export interface OrderSummaryLineItem { key: string; title?: string; className?: string; sortOrder: number; content: | string | JSXInternal.Element | VNode<HTMLAttributes<HTMLDivElement>> | OrderSummaryLineItem[] | undefined;}There are default order summary lines in the OrderSummary component (including several not shown here, such as shipping and gift wrapping). If no customization is needed, and therefore nothing is passed using the updateLineItems attribute, the default order summary lines will be rendered.
Let’s imagine that lineItems contains the following subset of those lines:
const lineItems: Array<OrderSummaryLineItem> = [ { key: 'subTotalContent', sortOrder: 100, content: subTotalContent, }, { key: 'discountsContent', sortOrder: 600, content: discountsContent, }, { key: 'taxContent', sortOrder: 800, content: taxContent, }, ];In the example above, the OrderSummary component renders the sub-total, discounts, and tax lines, in that order.
The value of the sortOrder attribute determines the order in which the lines are rendered.
The larger the sortOrder value, the lower the line will be rendered in the order summary.
The content attribute can be a string, a JSX element, or an array of OrderSummaryLineItem objects (whenever is not undefined).
For instance, you could choose to render a JSX element in a form of a OrderSummaryLine container.
This OrderSummaryLine container it is defined as follows:
export interface OrderSummaryLineProps extends HTMLAttributes<HTMLDivElement> { label: VNode | string; price: VNode<HTMLAttributes<HTMLSpanElement>>; classSuffixes?: Array<string>; labelClassSuffix?: string; testId?: string; children?: any;}See an example of how to use the OrderSummaryLine container below, where only the mandatory props are passed:
<OrderSummaryLine label={translations.subtotalLabel} price={subTotal.price} classSuffixes={['subTotal']} > {children} </OrderSummaryLine> );Note that the OrderSummaryLine container behaves like a wrapper for the OrderSummaryLine component.
The component ultimately decides how to render the line item based on the children attribute.
export interface OrderSummaryLineComponentProps extends HTMLAttributes<HTMLDivElement> { label: VNode | string; price: VNode<HTMLAttributes<HTMLSpanElement>>; classSuffixes?: Array<string>; labelClassSuffix?: string; testId?: string; children?: any;}Where to perform the customizations
Section titled “Where to perform the customizations”To customize the order summary lines, you need to render the Cart component passing the OrderSummary component as a slot.
When rendering the OrderSummary component, you can pass the updateLineItems attribute to customize the order summary lines as needed.
// Cart provider.render(Cart, { slots: { OrderSummary: (ctx) => { const orderSummary = document.createElement('div');
provider.render(OrderSummary, { updateLineItems: (lineItems) => { // Customize the order summary lines here return lineItems; } } } } });Examples
Section titled “Examples”For the examples shown below, assume that this is how Order Summary looks originally:

Remove Item: Remove total saved
Section titled “Remove Item: Remove total saved”The following example removes the Total saved line:
updateLineItems: (lineItems) => { const index = lineItems.map(item => item.key).indexOf('totalSavedContent'); lineItems.splice(index, 1);
return lineItems;}
Reorder items: Move primary action to the beginning
Section titled “Reorder items: Move primary action to the beginning”The following example moves the Checkout button to the top:
updateLineItems: (lineItems) => { lineItems.map(lineItem => { if (lineItem.key === 'primaryActionContent') { lineItem.sortOrder = 50; } return lineItem; });
return lineItems;};
Group items: Group subtotal and tax in an accordion
Section titled “Group items: Group subtotal and tax in an accordion”You can group and sort order summary lines into sections using the Accordion component from the Storefront SDK (Elsie) . For the full set of UI primitives, see the Storefront SDK components overview .
The following example groups the subtotal and tax in an accordion:
updateLineItems: (lineItems) => { const totalsIndex = lineItems.map(item => item.key).indexOf('taxContent'); const taxContent = lineItems.splice(totalsIndex, 1)[0]; const subtotalIndex = lineItems.map(item => item.key).indexOf('subTotalContent'); const subTotalContent = lineItems.splice(subtotalIndex, 1)[0]; lineItems.push({ key: 'subtotalTaxGrouped', sortOrder: 50, title: 'Subtotal and Tax', content: [ taxContent, subTotalContent, ], });
return lineItems;}
Add item: Add a new order summary line
Section titled “Add item: Add a new order summary line”The following example adds the FPT line:
updateLineItems: (lineItems) => { const totalFpt = ctx.data.items.reduce((allItemsFpt, item) => { const itemFpt = item.fixedProductTaxes.reduce((accumulator, fpt) => { accumulator.labels.push(fpt.label); accumulator.total += fpt.amount.value; return accumulator; }, { labels: [], total: 0 }); allItemsFpt.labels = [...allItemsFpt.labels, ...itemFpt.labels]; allItemsFpt.total += itemFpt.total; return allItemsFpt; }, { labels: [], total: 0 });
lineItems.push({ key: 'fpt', sortOrder: 350, title: 'Fixed Product Tax', content: OrderSummaryLine({label: "FPT(" + totalFpt.labels.join(',') + ')', price: Price({amount: totalFpt.total}), classSuffix: 'fpt'}) })
return lineItems;};
Related
Section titled “Related”- OrderSummary container — reference for the summary you customized.
- Add custom product lines to cart summary — a related cart summary customization.