# Discounts, notes and progress bars

> The parts you add to a cart - discount code and gift card fields, the list of discounts, a note and other fields saved on the order, a free shipping progress bar and a countdown.

Status: Ready (Smootify 2.0)  
1.x page: https://docs.smootify.io/docs/cart/additional-data  
URL: https://www.smootify.io/docs/build/cart-extras  
Updated: 2026-10-10

This page adds parts to the cart you built in [Build the cart](https://www.smootify.io/docs/build/cart): fields for discount codes and gift cards, the list of discounts, a note and other fields saved with the order, a free shipping progress bar and a countdown. Each part is optional. Add only the ones your store needs.

> [!NOTE]
> These parts need no plan or add-on, except file fields, which need the Server plan.

What the visitor types goes in fields of the cart’s Form, and Smootify reads each field by its **Name**, set in the field settings:

| Field Name | What it is | Field | Applied by | Shows |
|---|---|---|---|---|
| `Coupon` | a discount code | a Text field | a button with `data-action="coupon"`, or Enter | in the list of `cart="discount"` |
| `gift-card` | a gift card | a Text field | a button with `data-action="gift-card"` | in the list of `cart="gift-card"` |
| `Note` | the order note | a Text area or a Text field | saved at checkout | as the note of the order, in Shopify |
| any other name, such as `Delivery day` | a cart attribute | a Text field, Select, Checkbox or Radio button | saved at checkout | in the order's additional details, in Shopify |

## 1. Discount codes

The field and its button go inside the cart’s **Form**.

1. Add a Text field and set its **Name** to `Coupon` in the field settings. This is a Webflow setting, not a custom attribute.
2. Add a Custom element with the tag `button` and `data-action="coupon"`. A click applies the code. Pressing Enter in the field does the same.
3. Optional: inside the button, an element with the custom attribute `data-wait="Applying…"` shows that text while the code is applied.

If the field is empty, the browser asks the visitor to fill it. Once the code is applied, the field is emptied.

**A code in the link.** A link to any page of your site with `?discount=` and a code, such as `/boxes?discount=WELCOME10`, adds that code to the visitor’s cart when the page opens, with no cart element needed on the page: nobody has to type it. Use it in newsletters, ads and referral programs. The code is saved on the Shopify cart, so it stays on every page and visit until it is removed or the order is placed. You can send the link to a visitor whose cart is empty or under the code’s minimum: the code waits on the cart, also while other codes are typed or removed, and applies by itself once the cart qualifies. It shows in the `cart="discount"` list only from then. Removing it, or a new cart after an order, forgets it. A code that does not exist shows nowhere and does no harm at checkout.

**A cart paid on an invoice.** A cart with a chosen price ([name your price](https://www.smootify.io/docs/features/name-your-price), the [product configurator](https://www.smootify.io/docs/features/product-configurator)) or sent as a [quote](https://www.smootify.io/docs/features/quotes) becomes a Shopify draft order. The codes that apply to the cart go with it: the invoice opens with them already applied. Its own field still takes a gift card or another code.

**Show the discounts.** A Div block with `cart="discount"`, anywhere inside `smootify-cart`, is a template, repeated once for each code that applies and once for each automatic discount on the order, such as “10% off orders over $100”. Inside it:

- `discount="title"`: the code, or the name of the automatic discount;
- `discount="amount"`: the amount, such as ”-$10.00”;
- a Custom element with the tag `button` and `data-action="remove"`: removes the code. An automatic discount cannot be removed, so Smootify removes its button.

```html
<div>
  <input name="Coupon">
  <button data-action="coupon"><div data-wait="Applying…">Apply</div></button>
</div>
<div cart="discount">
  <div discount="title">CODE</div>
  <div discount="amount">-$0.00</div>
  <button data-action="remove">Remove</button>
</div>
```

Smootify gives the remove buttons of the discount and gift card lists `type="button"`, so removing a code does not submit the cart form.

A discount shows in one of two places, depending on what it lowers:

- **On the whole order**, `cart="discount"`: each code that applies and each automatic discount on the order, with `discount="title"`, `discount="amount"` and a remove button inside (an automatic discount loses its button).
- **On one line**, `cart-item="discount"` inside `cart-item`: each discount that lowers the price of that product, with `discount="title"` and `discount="amount"`; already off `cart="subtotal"`, never in the order list.

**Discounts on products.** A code or automatic discount that lowers the price of products shows on the lines, not in this list: `cart="subtotal"` already has it off. To show it on a line, add a Div block with `cart-item="discount"` inside `cart-item`, with `discount="title"` and `discount="amount"` inside it. It is repeated once for each discount on that line.

## 2. Gift cards

Gift cards work the same way as codes, inside the cart’s Form:

- a Text field with the **Name** `gift-card`;
- a Custom element with the tag `button` and `data-action="gift-card"`, which applies it. Pressing Enter in the gift card field does the same;
- a Div block with `cart="gift-card"`: a template repeated once for each gift card applied. Inside it, `gift-card="code"` shows the end of the code, such as ”•••• 4F2A”, and `gift-card="amount"` the amount used, removed when the card covers nothing. A button with `data-action="remove"` removes the card.

A second gift card is added next to the first: it does not replace it.

## 3. A note and other fields

Every field in the cart’s Form is saved with the order when the visitor checks out. In Shopify, you find them on the order, under its additional details.

- **The note.** Add a Text area, or a Text field for a short note, and set its **Name** to `Note`. Its text becomes the order note. When the cart already has a note, the field shows it.
- **Other fields.** Add any Text field, Select field, Checkbox or Radio button, such as a delivery day or a gift wrap option. The field’s **Name** becomes the name of the value saved on the order. These values are called cart attributes.

```html
<textarea name="Note" placeholder="A note for your order"></textarea>
<select name="Delivery day"><option value="Monday">Monday</option><option value="Friday">Friday</option></select>
<label class="w-checkbox"><input type="checkbox" name="Gift wrap" class="w-checkbox-input"><span class="w-form-label">Gift wrap</span></label>
```

How the fields behave:

- **Saved at checkout.** Smootify saves the note and the fields when the visitor clicks the checkout button, not while they type.
- **Empty fields** are not saved. A Checkbox saves `on` when it is ticked. A Select field that allows several choices saves them in one value, separated by commas.
- **Shown again.** When the cart renders, Text fields, Text areas, Select fields, Checkboxes and Radio buttons show the value already saved in the cart.
- **Required fields.** A field with Webflow’s **Required** setting must be filled before the visitor can check out. The buttons that apply a code or a gift card skip that check.
- **Attributes set by apps stay.** At checkout the form saves only the attributes it has fields for. Cart attributes that an app or a script set, under other names, are kept. A field of the form, even empty, replaces the attribute with its name.
- **Names Smootify keeps for itself.** Fields named `Coupon`, `Note`, `gift-card` or `quantity` are never saved as cart attributes.

**Files.** With the Server plan, a [`file-input`](https://www.smootify.io/docs/reference/elements/file-input) in the cart’s Form uploads a file to Shopify and saves it with the order. See [File uploads](https://www.smootify.io/docs/features/file-uploads).

For developers, [`updateCartNote`](https://www.smootify.io/docs/reference/api/methods/updatecartnote) and [`updateCartAttributes`](https://www.smootify.io/docs/reference/api/methods/updatecartattributes) do the same from code. The cart attributes Smootify writes itself are listed in [cart attributes](https://www.smootify.io/docs/reference/cart-attributes).

## 4. Free shipping progress bar

Add a Custom element with the tag `free-shipping-bar`. It follows the cart wherever it is: in the mini cart, on the cart page or on a product page.

Give it one custom attribute:

- `data-amount="100"`: free shipping from that amount. Smootify compares it with the cart total after discounts.
- `data-quantity="3"`: free shipping from that number of items.

Inside it:

- `data-prop="left"` on a text element: what is still missing, as an amount or a number of items;
- `data-prop="progress-width"` on a Div block: Smootify sets its width to the share of the goal reached, from 0% to 100%;
- `free-shipping-condition="needs-more"` and `free-shipping-condition="free-shipping"`: an element shown before and after the goal is reached.

```html
<free-shipping-bar data-amount="100">
  <div free-shipping-condition="needs-more">Add <span data-prop="left">$0.00</span> for free shipping</div>
  <div free-shipping-condition="free-shipping">You get free shipping</div>
  <div><div data-prop="progress-width"></div></div>
</free-shipping-bar>
```

With `data-amount="100"`, a cart of €65 and one of €120:

With `data-amount="100"`: a €65 cart shows `free-shipping-condition="needs-more"`, `data-prop="left"` is €35.00 and `data-prop="progress-width"` is 65% wide. A €120 cart shows `free-shipping-condition="free-shipping"`, the bar gets the class `is-free`, and the width goes past 100% (give its track Overflow: hidden).

- The bar is hidden until the cart loads. Once the goal is reached, it has the class `is-free`.
- Past the goal, the width keeps growing above 100%. Set the parent of the bar to **Overflow: hidden**.
- `data-amount` is the same number in every currency: `100` means $100 for one visitor and €100 for another.
- The bar only shows progress. The free shipping itself is a shipping rate or a discount you set up in Shopify, with the same amount.

## 5. Countdown

Add a Custom element with the tag `urgent-cart-countdown`, with `data-time` set to the number of minutes, such as `data-time="15"`. Inside it, `data-prop="minutes"` and `data-prop="seconds"` show the time left.

```html
<urgent-cart-countdown data-time="15" data-on-end="clear">
  <div>Your cart is saved for <span data-prop="minutes">15</span> min <span data-prop="seconds">0</span> s</div>
</urgent-cart-countdown>
```

- **When it starts.** When the cart has items, the countdown starts and its end time is saved in the cart. It keeps running across pages and reloads, and does not start again when more products are added. It is hidden while the cart is empty.
- **When it ends.** The cart is emptied. With `data-on-end="redirect"`, the visitor also goes to the page in `data-redirect-to`, or to the home page without it. `data-on-end="clear"`, the default, only empties the cart.
- **Where to put it.** The cart is emptied by a page that shows the countdown. Put it in the navbar or the mini cart, so it is on every page.
- **Seconds.** They are written without a leading zero: 5, not 05. A design like “4 min 5 s” reads better than “4:05”.

> [!WARNING]
> When the time runs out, the visitor's cart is really emptied. Use the countdown only for a real limit, such as products held for a set time.

## Before you publish

> [!STUCK]
> - **A discount code seems ignored.** Shopify did not apply it to this cart: the code does not exist, or its conditions are not met. The cart lists only the codes that apply, and shows no message for the others.
> - **The code is saved on the order instead of applied.** The field's Name is not `Coupon`, such as "Discount code". Rename it.
> - **The note is not saved.** The field's Name is not `Note`.
> - **The gift card is not applied, or Enter in its field goes to checkout.** The field's Name is spelled another way. Set it to `gift-card`.
> - **The progress bar spills out of its track.** Past the goal its width goes above 100%. Set the track to Overflow: hidden.

## Coming from 1.x

- The cart attributes that apps or scripts set are kept at checkout. 1.x replaced all the attributes with the fields of the form, and lost the others.
- A Text field named `Note` now saves the order note too. 1.x saved it only from a Text area.
- `cart="discount"` now also lists the automatic discounts on the order, without a remove button.
- `urgent-cart-countdown` shows the total minutes: 75 minutes left shows 75, where 1.x showed 15. It no longer needs the easytimer.js script.
