Skip to content

Discount codes

A discount-code form plus applied codes, amounts, savings, and errors.

A discount-code field for your cart drawer or page: shoppers apply a code, the applied code shows with a remove control, an error appears when Shopify rejects it, and the cart breaks the discount down into order-level rows, per-line strikethrough pricing, and a “you saved” total. Everything here lives at store level.

<!-- The code field: apply-discount owns YOUR input - label it yourself (SSK-501). -->
<apply-discount class="discount-form">
<input type="text" aria-label="Discount code" placeholder="Discount code" />
<button type="button">Apply</button>
</apply-discount>
<!-- Shown when Shopify kept a code but marked it not applicable. -->
<show-discount-error>That code isn't valid for this cart.</show-discount-error>
<!-- The applied code(s), with a control to remove them. -->
<div class="applied-code">
Code: <show-discount-code></show-discount-code>
<remove-discount class="muted">Remove</remove-discount>
</div>
<!-- One chip per applied code; the first <cart-discount> is the clone template. -->
<cart-discount-list class="chips">
<cart-discount class="chip"><show-discount-amount></show-discount-amount></cart-discount>
</cart-discount-list>
<!-- One row per order-level allocation (code or automatic), with an amount. -->
<cart-order-discount-list>
<cart-discount>Discount: <show-discount-amount></show-discount-amount></cart-discount>
</cart-order-discount-list>
<!-- Line-level discounts render per line, inside the cart-line template. -->
<cart-line-list>
<cart-line>
<show-line-title></show-line-title>
<show-line-original-price class="strike"></show-line-original-price>
<show-line-price></show-line-price>
<show-line-discount class="muted"></show-line-discount>
</cart-line>
</cart-line-list>
<!-- Totals: each hides itself via [ss-empty] when nothing applies. -->
<div>Discount: <show-cart-discount></show-cart-discount></div>
<div>You saved: <show-cart-savings></show-cart-savings></div>
  • <apply-discount> wraps your <input> (required) and optional <button>. It applies on Enter or click, then clears the input. The aria-label is on you (SSK-501).
  • <cart-order-discount-list> clones one <cart-discount> per order-level allocation, code or automatic. Line-level discounts show inside each <cart-line> via <show-line-original-price> and <show-line-discount>. <cart-discount-list> is the per-code variant, one chip per applied code.
  • <show-cart-discount> is the total order-level discount; <show-cart-savings> sums all line-level and order-level discounts.
TagAttributeType / defaultWhat it does
remove-discountcodestring, ""Remove just that code; empty removes all applied codes.
apply-discount--No attributes. Requires a nested <input>; optionally a <button>.
cart-discount-list / cart-order-discount-list--Template-clone containers: first <cart-discount> child is the template.

The displayers take no attributes.

Almost every tag here sets [ss-empty] when it has nothing to show, so whole rows can collapse:

show-discount-error { color: #b00020; }
show-discount-error[ss-empty], cart-discount-list[ss-empty], cart-order-discount-list[ss-empty] { display: none; }
.applied-code:has(show-discount-code[ss-empty]) { display: none; }
show-line-original-price { text-decoration: line-through; color: #888; }
show-line-original-price[ss-empty], show-line-discount[ss-empty], show-cart-savings[ss-empty] { display: none; }

You own the copy inside <show-discount-error>; the engine only clears [ss-empty] when the cart holds a code Shopify kept but marked not applicable.

  • The code doesn’t apply without a nested <input>, a <storesynk-store> ancestor (SSK-101), or an accessible name (SSK-501). See cart troubleshooting.
  • <show-discount-amount> must sit inside a <cart-discount> inside a discount list (SSK-105/SSK-106), the same shape as cart-line-listcart-lineshow-line-*.
  • A kept-but-invalid code shows no visible failure unless you author a <show-discount-error>.