Cart and checkout slots
Where the cart page, its order summary and the thank-you page expose slots, and what each one receives.
Use these slots when you want a free-shipping message above the cart lines, a note beside the checkout button, or an upsell on the order-confirmation page, without forking the route. New to slots? Read Slots and Page frame slots first.
Cart page
Route: Cart. The cart slots render only when the cart has items. An empty cart shows an empty state, and none of them appear.
cart:startcart:items.startcontext: cartItemscart:items.endcart:summary.startcart:submit.startcart:submit.endcart:summary.endcart:end| Slot | Position | Context | Notes |
|---|---|---|---|
cart:start | After the breadcrumb and conditional offer, before the two-column layout. Full width. | none | Good for a banner above everything. |
cart:items.start | At the top of the left column, before the first cart line. | cartItems | cartItems is the array of cart lines. |
cart:items.end | At the bottom of the left column, after the cart lines, product options and offers. | none | |
cart:summary.start | At the top of the order summary (right column), before the free-shipping bar. | none | The summary is sticky on large screens. |
cart:submit.start | Directly before the "Complete Order" button. | none | |
cart:submit.end | Directly after the "Complete Order" button. | none | Good for payment icons or a returns note. |
cart:summary.end | At the bottom of the order summary, after the checkout button. | none | The tiered-offer widget renders below this slot. |
cart:end | After the two-column layout, at the bottom of the page container. | none | Full width. |
cart:items.start is the only cart slot with its own context: { cartItems }. The other slots pass nothing. Every handler also receives twilight, so cart:items.start handlers get { cartItems, twilight }.
Example: free-shipping banner above the cart items
import { hookRegistry, HookName, type HookContext } from '@salla.sa/twilight-theme-engine/hooks';
export function registerThemeHooks() {
hookRegistry.register(
HookName.CART_ITEMS_START,
(context: HookContext) => {
const { cartItems } = context as { cartItems?: unknown[] };
if (!cartItems?.length) return null;
return (
<div className="mb-4 rounded-md bg-gray-100 p-3 text-sm">
{cartItems.length} item(s) in your cart. Orders over 200 SAR ship free.
</div>
);
},
50
);
}Call registerThemeHooks() once at module scope, as in Add content to a slot.
Thank-you page
Route: Thank you. The customer lands here after placing an order.
thank-you:startthank-you:items.startthank-you:items.endthank-you:end| Slot | Position | Context | Notes |
|---|---|---|---|
thank-you:start | First thing on the page, above the colored header band. | none | |
thank-you:items.start | In the confirmation block, after the order number, instructions and messages. | none | |
thank-you:items.end | Immediately after thank-you:items.start. | none | The two slots are adjacent with nothing between them, so they render back to back. They always render. |
thank-you:end | Last item inside the page container, after the contact details. | none | Good for a "follow us" or referral block. |
None of the thank-you slots pass the order in their context. If you need order data, load it yourself in your handler's component.