CartSummary
The cart page sidebar: free-shipping bar, loyalty and gift widgets, totals, a coupon box and the Complete Order button.
import { CartSummary } from '@salla.sa/twilight-theme-engine/components/cart';In plain words
The box beside the cart lines: how far the shopper is from free shipping, the items total, shipping, discount and VAT rows, the grand total, a coupon field, and the button that starts checkout.
You pass the cart you read. It is lazy, so it goes inside <Suspense>.
Signature
const CartSummary: React.LazyExoticComponent<(props: {
cart: Cart;
applyCouponEnabled?: boolean; // true
taxAmount?: number; // 0 or missing: no VAT row
loyalty?: Cart['loyalty'];
gift?: Cart['gift'];
loyaltyPoints?: number; // the customer's points
}) => JSX.Element>Try it live
import { Suspense } from 'react';
import { CartSummary } from '@salla.sa/twilight-theme-engine/components/cart';
import { useStore } from '@salla.sa/twilight-theme-engine/hooks/useStore';
import type { Cart } from '@salla.sa/twilight-theme-engine/types';
export function Summary({ cart, points }: { cart: Cart; points?: number }) {
const { settings } = useStore();
return (
<Suspense fallback={null}>
<CartSummary
key={cart.id}
cart={cart}
applyCouponEnabled={settings.cart?.apply_coupon_enabled}
taxAmount={cart.tax_amount}
loyalty={cart.loyalty}
gift={cart.gift}
loyaltyPoints={points}
/>
</Suspense>
);
}
Example
import { Suspense } from 'react';
import { CartSummary } from '@salla.sa/twilight-theme-engine/components/cart';
import { useStore } from '@salla.sa/twilight-theme-engine/hooks/useStore';
import type { Cart } from '@salla.sa/twilight-theme-engine/types';
export function Summary({ cart }: { cart: Cart }) {
const { settings } = useStore();
return (
<Suspense fallback={null}>
<CartSummary
key={cart.id}
cart={cart}
applyCouponEnabled={settings.cart?.apply_coupon_enabled}
taxAmount={cart.tax_amount}
loyalty={cart.loyalty}
gift={cart.gift}
/>
</Suspense>
);
}
How it behaves
Rows and their conditions: free-shipping bar (
cart.free_shipping_bar), loyalty (loyaltyandloyaltyPoints), gifting (gift.enabled), items total, options total (cart.optionsnot empty), shipping (has_shipping), coupon box (applyCouponEnabled), discount (total_discount), VAT (taxAmount), total. Amounts go throughuseMoney().format.The coupon box uses
useCoupon(): it applies on submit, and the same button removes an applied coupon. Errors show under the field.Hook slots, without context:
cart:summary.start,cart:submit.start(the engine puts a price-quote button there when the store has that feature),cart:submit.end,cart:summary.end.Complete Order calls
Salla.cart.submit(), which starts checkout.SallaTieredOfferrenders under the box.The engine's cart page passes
applyCouponEnabled={store.settings?.cart?.apply_coupon_enabled},taxAmount={cart.tax_amount}, the cart'sloyaltyandgift,loyaltyPointsfromloyalty.queries.points(), andkey={cart.id}.
Gotchas
Complete Order swallows every error from
Salla.cart.submit()(an emptycatch), so a failed checkout start does nothing visible. Listen to the SDK's events if you need to react.When the cart has
loyalty, a customer withloyaltyPointsof0gets a stray "0": the loyalty card is guarded withloyalty && loyaltyPoints && (…), and React renders the number. Passundefinedinstead of0.The coupon box keeps its own state: it shows
useCoupon().value ?? cart.couponin an uncontrolled input (defaultValue). Removing a coupon the cart was loaded with falls back tocart.coupon, so the box still shows it as applied; a coupon that arrives with a re-read cart leaves the field disabled but empty. Re-read the cart after a change and give the summary akeythat changes with each read (the demo usesdataUpdatedAt). The engine's cart page useskey={cart.id}, which never changes.taxAmountalso switches the first row's label: with any truthy value it reads "Items total (excl. tax)", otherwise "Items total".
Related
One line of the cart page: picture, name, prices, offers, a quantity input and a delete button that change the shopper's real cart.
useCouponApplies or removes a discount coupon on the shopper's cart through the Salla SDK, with loading and error state.
registerDefaultHooksRegisters the engine's built-in slot handlers (GTM, bundles, store closed, fast checkout, price quote, pre-order); importing the hooks module already runs it.