Cart
The cart is a Commerce system template. When the Commerce extension is enabled, the runtime fills its tokens with the current cart before the page is served. This page lists the summary tokens, the loop over line items, and the conditional that shows an empty state. A token with no value renders as an empty string, and cart values are only populated while Commerce is enabled.
Cart summary tokens
Write these tokens anywhere on the cart template. Amount tokens return a plain number string, so print the currency symbol next to them.
| Token | Meaning | Example |
|---|---|---|
{cart.count} | Total quantity of items in the cart | {cart.count} items |
{cart.total} | Cart total after tax and discounts | {cart.currency_symbol}{cart.total} |
{cart.currency_symbol} | Currency symbol from project settings | <span>{cart.currency_symbol}{cart.total}</span> |
{cart.subtotal} | Sum of line totals before tax and discounts | {cart.currency_symbol}{cart.subtotal} |
{cart.tax} | Tax amount for the cart | {cart.currency_symbol}{cart.tax} |
{cart.coupon_discount_total} | Total discount from applied coupons | {cart.currency_symbol}{cart.coupon_discount_total} |
{cart.currency} | Currency code, such as USD | {cart.currency} |
{cart.has_coupons} | True when at least one coupon is applied | {if cart.has_coupons}...{/if} |
{cart.empty} | True when the cart has no items | {if cart.empty}...{/if} |
<div class="cart-summary">
<p>{cart.count} items</p>
<dl>
<dt>Subtotal</dt><dd>{cart.currency_symbol}{cart.subtotal}</dd>
<dt>Tax</dt><dd>{cart.currency_symbol}{cart.tax}</dd>
<dt>Discount</dt><dd>{cart.currency_symbol}{cart.coupon_discount_total}</dd>
<dt>Total</dt><dd>{cart.currency_symbol}{cart.total}</dd>
</dl>
</div>
Looping over cart items
The cart.items collection holds one entry per line in the cart. Open the loop with {each cart.items as=item}, read each line's fields with {item.*}, and close it with {/each}.
{each cart.items as=item}
<article class="cart-item">
<img src="{item.image}" alt="{item.name}">
<h3>{item.name}</h3>
{if item.variant}
<p class="text-sm">{item.variant}</p>
{/if}
<p>{item.quantity} x {cart.currency_symbol}{item.unit_price}</p>
<p class="font-bold">{cart.currency_symbol}{item.line_total}</p>
</article>
{/each}
The alias defaults to item, so as=item may be omitted, but keep it explicit when a cart loop is nested. You may also label the closing tag with the collection name, {/each cart.items}, for readability. The label is ignored at render time.
Cart item fields
Inside the loop, the current line is available as {item.*}.
| Field | Meaning |
|---|---|
{item.name} | Product name, using the variant title when the line has one |
{item.variant} | Variant title for the line, empty when there is no variant |
{item.variant_label} | Raw variant label |
{item.variant_sku} | Variant SKU |
{item.image} | Product image URL |
{item.quantity} | Quantity on the line |
{item.unit_price} | Price per unit, as a plain number string |
{item.line_total} | Quantity multiplied by the unit price |
{item.product_id} | Product id |
{item.variant_id} | Variant id, empty when there is no variant |
{item.id} | Cart line id |
{item.index} | 1-based position of the line in the loop |
Print a currency symbol before {item.unit_price} and {item.line_total}, since those values carry no symbol. A field with no value renders as an empty string, so guard optional fields such as {item.variant} with {if}.
Empty-cart handling
An {each} over an empty cart renders nothing and can leave an empty list behind. Wrap the cart contents in {if cart.count} and add an {else} for the empty state. {cart.count} is 0 for an empty cart, which is false in a condition. {cart.empty} is the equivalent explicit test.
{if cart.count}
<div class="cart-summary">
<p>{cart.count} items</p>
<p>Total: {cart.currency_symbol}{cart.total}</p>
</div>
{each cart.items as=item}
<article class="cart-item">
<h3>{item.name}</h3>
<p>{item.quantity} x {cart.currency_symbol}{item.unit_price}</p>
<p>{cart.currency_symbol}{item.line_total}</p>
</article>
{/each}
{else}
<div class="cart-empty">
<h2>Your cart is empty</h2>
<p>Add a product to continue.</p>
<a href="{page_link id=10}">Continue shopping</a>
</div>
{/if}
The page_link tag resolves the URL of a page by its id, so the button needs no hardcoded path. See Variables and tokens and Links and blocks for those general tags.
Presentation fields
The price summary loop exposes presentation helpers for amounts. {item.display_amount} prints an amount with its currency symbol plus the free and pending states, and {item.amount_class} returns a text color class for the amount. These fields belong to {each checkout.price_summary as=item} on the Checkout template. The cart item loop does not expose them.
The bundled cart page
The bundled cart page marks its regions with client-side hooks rather than the summary tokens above. data-cart and data-cart-page identify the page, data-cart-empty and data-cart-summary toggle the empty and filled states, and a data-cart-item-template element is cloned once per line. A custom cart template can use either approach, but the {cart.*} tokens and the cart.items loop are the ones a server-rendered template reads.

