CartTotalSummary
Description
A headless render props component that provides cart summary data including subtotal, discount, shipping, tax, and grand total. When no children function is provided, it renders a DefaultCartSummary with Area-based extension points. When children is provided, it acts as a pure headless component.
Role in Theming
CartTotalSummary is one of EverShop's headless components — it owns the data extraction and tax-aware price formatting while leaving UI decisions to its parent:
- With no children, CartTotalSummary renders a default summary layout with Areas (
cartSummaryBeforeSubTotal,cartSummaryAfterSubTotal, etc.) that extensions can inject into. - With children, it renders nothing of its own — only what the
childrenfunction returns. - Theme developers override the parent components that use CartTotalSummary (
ShoppingCart,Checkout) to change the summary layout. - The data logic stays stable across themes. Tax-inclusive/exclusive price selection, loading state derivation, and cart data extraction are encapsulated.
Theme Override Points
CartTotalSummary is consumed by these components, which are the actual override targets for theme developers:
| Parent Component | Route | Override Path in Theme |
|---|---|---|
| ShoppingCart | cart | themes/<name>/src/pages/cart/ShoppingCart.tsx |
| Checkout | checkout | themes/<name>/src/pages/checkout/Checkout.tsx |
Import
import {
CartTotalSummary,
DefaultCartSummary,
Subtotal,
Discount,
Shipping,
Tax,
Total
} from '@components/frontStore/cart/CartTotalSummary';
Usage
With Default Renderer
When no children are provided, it renders the built-in summary layout:
import { CartTotalSummary } from '@components/frontStore/cart/CartTotalSummary';
function CartSummary() {
return <CartTotalSummary />;
}
As Headless Component
Pass a children function to take full control of the rendering:
import { CartTotalSummary } from '@components/frontStore/cart/CartTotalSummary';
function CustomCartSummary() {
return (
<CartTotalSummary>
{({ subTotal, total, loading, taxAmount, showPriceIncludingTax }) => (
<div className="my-summary">
<div>Subtotal: {subTotal}</div>
{!showPriceIncludingTax && <div>Tax: {taxAmount}</div>}
<div>Total: {total}</div>
</div>
)}
</CartTotalSummary>
);
}
Props
| Name | Type | Required | Description |
|---|---|---|---|
| children | RenderFunction | No | Optional render function. If omitted, DefaultCartSummary is used. |
Render Function Props
When children is provided, the render function receives:
| Name | Type | Description |
|---|---|---|
| loading | boolean | True when any cart operation is in progress |
| showPriceIncludingTax | boolean | Whether prices include tax (from store config) |
| noShippingRequired | boolean | True when cart has no shippable items |
| subTotal | string | Formatted subtotal (tax-inclusive or exclusive based on config) |
| discountAmount | string | Formatted discount amount |
| coupon | string | undefined | Applied coupon code, if any |
| shippingMethod | string | undefined | Selected shipping method name |
| shippingCost | string | undefined | Formatted shipping cost |
| taxAmount | string | Formatted total tax amount |
| total | string | Formatted grand total |
Exported Sub-Components
CartTotalSummary also exports individual summary row components used by DefaultCartSummary. Theme developers can import and compose these individually:
| Component | Props | Description |
|---|---|---|
| Subtotal | subTotal, loading | Subtotal row |
| Discount | discountAmount, coupon, loading | Discount row with coupon form/remove |
| Shipping | method, cost, noShippingRequired, loading | Shipping method and cost row |
| Tax | showPriceIncludingTax, amount, loading | Tax row (hidden when prices include tax) |
| Total | total, totalTaxAmount, priceIncludingTax, loading | Grand total row |
Examples
Custom Summary Layout
import { CartTotalSummary } from '@components/frontStore/cart/CartTotalSummary';
function MinimalSummary() {
return (
<CartTotalSummary>
{({ subTotal, total, coupon, discountAmount, loading }) => (
<div className="summary">
<div className="row">
<span>Subtotal</span>
<span>{subTotal}</span>
</div>
{coupon && (
<div className="row discount">
<span>Discount ({coupon})</span>
<span>{discountAmount}</span>
</div>
)}
<div className="row total">
<span>Total</span>
<span>{loading ? '...' : total}</span>
</div>
</div>
)}
</CartTotalSummary>
);
}
Theme Override Example
A theme developer overrides the cart page summary. Create this file in your theme:
themes/my-theme/src/pages/cart/ShoppingCart.tsx
import { CartTotalSummary } from '@components/frontStore/cart/CartTotalSummary';
import { CartItems } from '@components/frontStore/cart/CartItems';
function ShoppingCart() {
return (
<div className="my-theme-cart">
<CartItems>
{({ items, isEmpty, onRemoveItem }) => (
/* Custom cart items layout */
<div>{/* ... */}</div>
)}
</CartItems>
<CartTotalSummary>
{({
subTotal,
total,
taxAmount,
shippingMethod,
shippingCost,
showPriceIncludingTax,
noShippingRequired,
loading
}) => (
<div className="my-theme-summary">
<div>Subtotal: {subTotal}</div>
{shippingMethod && !noShippingRequired && (
<div>Shipping ({shippingMethod}): {shippingCost}</div>
)}
{!showPriceIncludingTax && <div>Tax: {taxAmount}</div>}
<div className="grand-total">
Total: {loading ? 'Calculating...' : total}
</div>
</div>
)}
</CartTotalSummary>
</div>
);
}
export default ShoppingCart;
export const layout = {
areaId: 'content',
sortOrder: 10
};
Default Cart Summary Areas
When using CartTotalSummary without children, the DefaultCartSummary renders with these Area extension points (in order):
cartSummaryBeforeSubTotalcartSummaryAfterSubTotalcartSummaryBeforeDiscountcartSummaryAfterDiscountcartSummaryBeforeShippingcartSummaryAfterShippingcartSummaryBeforeTaxcartSummaryAfterTaxcartSummaryBeforeTotalcartSummaryAfterTotal
Extensions can inject components into these areas without overriding the entire summary.
Features
- Headless or Default: Works as headless (with children) or renders a default layout (without children)
- Tax-Aware: Automatically selects tax-inclusive or exclusive prices based on store config
- Loading State: Derives loading from all cart operation states
- Area Extension Points: Default renderer includes Areas for extension injection
- Composable Sub-Components: Individual row components can be imported and reused
- Type Safe: Full TypeScript support
Related Components
- CartContext - Shopping cart context
- CartItems - Cart items display
- Coupon - Coupon management
Support us
EverShop is an open-source project that relies on community support. If you find our project useful, please consider sponsoring us.