Cart
The /cart page. Lines on the left, a summary column alongside carrying gift wrap, the free-shipping bar, discounts, the subtotal, checkout and an optional shipping estimator.
Most add-to-carts in Signal land in the cart drawer rather than here, so treat this page as the considered view — the one a shopper opens to edit an order, read a note field or estimate shipping.
Section settings
Section titled “Section settings”| Setting | Type | Default | What it does |
|---|---|---|---|
| Heading | Text | Your bag | The page <h1> |
| Empty heading | Text | Nothing here yet | Heading when the cart is empty |
| Empty button label | Text | Shop the drop | Button under it, linking to all products |
| Allow an order note | Checkbox | true | Allow an order note |
| Note label | Text | Order note | Label on the note field |
| Tax note | Text | Tax and shipping calculated at checkout. | Fine print above the checkout button |
| Free shipping unlocked | Text | Free shipping — unlocked | Shown once the threshold is met |
| Free shipping remaining | Text | from free shipping | Follows the remaining amount, e.g. “$40.00 from free shipping” |
| Checkout label | Text | Checkout | Submit button label |
| Continue label | Text | Continue shopping | Link under the button |
| Show a shipping estimator | Checkbox | true | Show a shipping estimator so shoppers can check delivery cost before checkout |
The section also accepts @app blocks, rendered in their own row under the lines — reviews, loyalty widgets, trust badges.
What each line shows
Section titled “What each line shows”| Element | Source |
|---|---|
| Thumbnail | item.image at 400w, linking to the product |
| Title | item.product.title |
| Variant | item.variant.title, suppressed when it is blank or Default Title |
| Subscription | item.selling_plan_allocation.selling_plan.name when the line is a subscription |
| Line item properties | Every entry in item.properties, as Name: value |
| Discounts | Each line_level_discount_allocations entry as Title −amount in the accent colour |
| Unit price | item.original_price with “each” |
| Line total | item.final_line_price, with the original struck through when a discount applied |
Quantity updates
Section titled “Quantity updates”The +, − and Remove controls all post to /cart/change.js with a line number and a quantity, handled by the theme’s global cart engine. On the cart page they additionally carry data-reload, so the page reloads after a successful change — the totals, the free-shipping bar and the discount rows are all server-rendered here, and a reload is the honest way to keep them consistent.
Errors are surfaced as a toast, with distinct copy for a network failure versus a store-side refusal, and the control is re-enabled rather than left spinning.
The order note
Section titled “The order note”With show_note on, the cart page shows a textarea under the lines. It saves itself:
- typing debounces for 500ms then posts to
/cart/update.js - blurring the field flushes immediately
- submitting the cart form (clicking Checkout) holds the submit just long enough to land a pending note, then lets it through — so a note typed and immediately checked out is never lost
The same behaviour drives the note field in the cart drawer.
Gift wrap
Section titled “Gift wrap”Shared with the drawer, and driven entirely by global settings under Theme settings → Cart:
| Setting | What it does |
|---|---|
| Gift wrap product | The wrap itself. Nothing renders unless this is set and the product is available |
gift_wrap_label (default Add gift wrapping) | The checkbox label; the wrap’s price is appended automatically |
gift_message_enabled (default on) | Adds a 200-character message field, revealed once wrapping is ticked |
The wrap is a real product, not a free-floating attribute — so it is priced, taxed, counted in inventory and fulfilled like anything else, rather than being a flag that never reaches the packing bench. Ticking the box adds that product’s line; unticking finds and removes it.
The checkbox state is derived by looking for the wrap’s variant id in the cart, so swapping the wrap product in settings does not leave a stale line ticked. If the add or remove fails, the checkbox is put back where the cart actually is.
The gift message is stored as the cart attribute Gift message — which is what shows on the order in admin — and saved on a 500ms pause rather than per keystroke.
The free-shipping bar
Section titled “The free-shipping bar”Driven by the global Cart → Free shipping threshold setting. When that setting is empty or zero, the bar does not render at all. When it is set, the bar shows either ship_unlocked or remaining + ship_away, with a progress track clamped at 100%.
The shipping estimator
Section titled “The shipping estimator”With show_estimator on, a <details> panel offers country, province and postal code, then calls /cart/shipping_rates.json and lists each rate with its price.
- The province field is populated from Shopify’s own country data and stays hidden for countries that have no provinces.
- A
422from Shopify is read rather than replaced with a generic failure, so an invalid postcode produces Shopify’s own explanation. - With no rates for the address, a dedicated “no rates” message is shown rather than an empty list.
- Output is announced via
role="status"andaria-live="polite".
The summary
Section titled “The summary”Above the subtotal, each cart-level discount renders as its own row. The subtotal uses cart.total_price. Below it: the tax_note, the checkout submit, and the continue-shopping link.
Related
Section titled “Related”- Cart drawer — the overlay version
- Product