> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Build a Box

> The Build a Box post-purchase offer: shoppers assemble a custom box from products you curate, with volume discounts that deepen as the box fills.

**Build a Box** is a post-purchase offer type where the shopper assembles their own box from a set of products you curate, and buys the whole selection in one transaction. Instead of accepting or declining a single product, they choose what goes in and how many, and a volume discount can deepen as the box fills.

It sits alongside the single-product and multi-product post-purchase offers, and composes with the usual offer widgets such as the heading and timer.

<Note>
  Build a Box offers several different products. To sell more units of one product at tiered prices, use [Quantity upsells](/aftersell/quantity-upsells) instead.
</Note>

To add one, open the funnel, select **Add offer**, and choose **Build a box**.

## Setting up the box

### Choosing candidate products

The **Product selection** section controls which products a shopper can choose from. These are called *candidates*.

1. Open the box offer in the post-purchase funnel editor.
2. Expand **Product selection**.
3. Select **Add product** and pick one or more products. Products already on the list are excluded from the picker.
4. Save.

A box supports up to **12 candidates**. Drag the handle on a row to reorder — that's the order shoppers see. Use the delete icon to remove one; you can't remove the last remaining candidate, since a box needs at least one.

### Box size

**Box size** sets how many items the shopper must choose:

| Setting                      | What it does                                                                |
| ---------------------------- | --------------------------------------------------------------------------- |
| **Minimum items**            | The floor. Counted in items, so three of one product counts as three.       |
| **Maximum items (optional)** | Leave empty for no limit. Set it equal to the minimum for a fixed-size box. |

With a fixed-size box, the editor notes that shoppers must choose exactly that many items and will see a "0 of N selected" counter.

<Warning>
  If your candidates can't collectively reach the minimum, the editor shows a critical banner titled **"This box won't be shown to shoppers"**, naming the most items your products do allow and the minimum you set. The offer is skipped entirely at serve time.

  The fix it suggests depends on the cause:

  * **A product has its quantity selector turned off**, so it can only be added once — turn one back on, add more products, or lower the minimum.
  * **Otherwise** — lower the minimum, add more products, or raise a product's maximum quantity.
  * **The box maximum admits no items at all** — the banner says so instead, and asks you to raise it or leave it empty.
</Warning>

## Discounts

### Discount tiers

The **Box discount** section sets a discount that scales with how many items are in the box. Add a tier with **Add tier**, then set **Minimum items for tier N** and **Discount for tier N**.

How the rate is chosen:

* The shopper gets the **deepest** rate their box qualifies for, not simply the last threshold crossed. If you configure 3+ items at 30% and 6+ items at 20%, a shopper with 6 items still gets 30%.
* The rate is evaluated at the **live item count**, not at the box minimum. A tile opens at full price and re-prices as the box fills, so the rate a shopper is quoted is always the rate their current selection actually earns.
* An empty tier table is valid and means the box sells at full price.

There is no box-wide discount cap — the tier table is the only thing that sets the rate.

The editor shows advisory warnings for three tier shapes that look unintended. None of them block saving:

| Warning                                                                            | When it appears                              |
| ---------------------------------------------------------------------------------- | -------------------------------------------- |
| A tier discounts less than a smaller tier, so it never applies                     | A deeper tier is shallower than one below it |
| A tier sits below the box minimum, so every box a shopper can buy already earns it | A tier's minimum is under the box floor      |
| Two tiers both start at the same number of items                                   | Duplicate tier minimums                      |

### Per-product discounts

A candidate can carry its own discount instead of following the box rate. Open the candidate, go to **Discount**, and check **Give this product its own discount**.

* The override applies on that product's tile and in the box total, in place of the tier rate.
* `0` is a valid override — it holds a product at full price inside an otherwise discounted box.
* Leave the override off to follow the box discount.

### Editing several products at once

**Edit all products** opens a bulk panel. Uncheck any candidate you want to leave out of the edit.

Where the selected products differ, a field shows **Mixed** — editing it writes your value to all of them, and leaving it alone preserves each product's own value. The override toggle shows an indeterminate state when only some have overrides.

## Per-product settings

Each candidate has its own panel, covering **Badge**, **Product image badge**, **Image**, **Product details** (including review ratings, with star colours defaulting to `#fdcc0d` and `#d1d5db`), **Variant options**, **Box limits**, **Discount**, and **Already purchased**.

Tile appearance is not set per candidate. It comes from the offer-level [**Layout**](#layout) setting, so every tile in a box is shaped the same way.

Two settings under **Box limits** are worth calling out:

* **Show quantity selector** — on by default. Turn it off so each add puts in exactly one unit, with no per-tile quantity stepper.
* **Maximum quantity in a box** — leave empty for no limit, or set it to 1 to keep a variety box varied.

The **Already purchased** section controls what happens when a shopper already has this product — bought on the current order or accepted at an earlier step in the funnel. Matched on product ID, so a different variant of a purchased product still counts. Choose one of three treatments:

| Option                         | What it does                                                                                                                                                   |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Show normally**              | The product appears in the box with no special treatment (default).                                                                                            |
| **Show a "Your choice" badge** | The product stays in the box and a pill badge marks it as one the shopper already has.                                                                         |
| **Hide the product**           | The product is dropped from the box entirely. Not available for most/least expensive candidates, which are resolved from the order after this setting is read. |

When **Show a "Your choice" badge** is selected, three additional settings appear:

* **Badge text** — the wording on the badge. Leave blank to use your store's translation (set in **Settings > Translations** under **Already purchased badge**). Defaults to "Your choice".
* **Badge color** — the fill color of the badge pill (hex, default `#008060`).
* **Badge text color** — the text color inside the badge pill (hex, default `#ffffff`).

The badge is visible in the funnel editor preview, so you can see how it looks before publishing.

## Layout

**Layout**, under the box's layout settings, sets the tile shape and how many tiles share a row:

| Layout            | How it looks                                                                              |
| ----------------- | ----------------------------------------------------------------------------------------- |
| **Classic**       | Image beside the text, two products per row.                                              |
| **Compact grid**  | Image above the text, three per row, one per row on a phone.                              |
| **Spotlight**     | The first product leads at half width, the rest follow in the compact grid.               |
| **Split columns** | Products on the left, with the total and the buy button in their own column on the right. |

The same section sets the padding around the box.

## Progress

**Box progress** controls the fill indicator:

| Setting                  | Options                                          | Default            |
| ------------------------ | ------------------------------------------------ | ------------------ |
| **Position**             | Above the products / Above the buy button / Both | Above the products |
| **Show progress bar**    | On / off                                         | On                 |
| **Bar color**            | Hex                                              | `#008060`          |
| **Bar position**         | Above the text / below the text                  | Above the text     |
| **Top / bottom padding** | 0–10, in steps of 2                              | 0                  |

There is no "hidden" position. To drop the progress line entirely, clear the progress text field.

### Progress text variables

Type `{` in any of the three [progress wording](#progress-wording) editors to insert a variable.

| Variable                                              | What it shows                                                                                                                                                                                             |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{box-progress}`                                      | The whole default progress sentence. It changes structure across the box's states, which no single hand-written sentence can do — see [Progress wording](#progress-wording) to reword each state instead. |
| `{items-in-box}`                                      | How many items are currently in the box.                                                                                                                                                                  |
| `{items-to-go}`                                       | The raw remaining count to the minimum.                                                                                                                                                                   |
| `{box-minimum}`                                       | The box minimum.                                                                                                                                                                                          |
| `{box-maximum}`                                       | The box maximum.                                                                                                                                                                                          |
| `{current-discount}`                                  | The rate currently in effect.                                                                                                                                                                             |
| `{next-discount}`                                     | The rate unlocked by adding more items. Blank at the deepest tier.                                                                                                                                        |
| `{items-to-next-discount}`                            | How many more items are needed to reach it. Blank at the deepest tier.                                                                                                                                    |
| `{subtotal}` / `{total}` / `{discount}` / `{savings}` | Box prices, summed across the whole selection. Blank until a price resolves.                                                                                                                              |
| `{first-name}`                                        | The shopper's first name.                                                                                                                                                                                 |
| `{timer}` / `{timer-end}`                             | The offer countdown.                                                                                                                                                                                      |

The step-header variables available on multi-product offers have no box equivalent and are not offered here.

### Progress wording

**Progress wording** is three rich text editors, one for each stage of filling the box. Type `{` in any of them to insert a [variable](#progress-text-variables). Clear a field to hide the progress line in that state.

| Editor                               | When its line shows                                                                                                                           |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **Before the minimum items reached** | While the box is short of its minimum. The shopper can't check out yet, so this line is the only thing explaining why the button is disabled. |
| **Between minimum and maximum**      | Once the box is past its minimum, while a deeper discount or the maximum is still ahead.                                                      |
| **Maximum items hit**                | Once the box has everything it can get: the maximum, or the deepest discount on a box with no maximum.                                        |

The editor shows only the fields your box can actually reach:

* **Before the minimum items reached** appears only when the box has a minimum above zero.
* **Between minimum and maximum** appears only when the box has a maximum or at least one discount tier. With neither, passing the minimum is already the end state.
* **Maximum items hit** always appears. Every box reaches it.

Because these are rich text editors, you can bold, colour, and resize the wording, not just change the words.

Changing the box **Language** re-translates any wording you haven't edited. Once you edit a field, it's left exactly as you typed it.

## Tile button text

The **Tile button text** section in the Buttons panel lets you customize the wording on the Add and Remove buttons that appear on each candidate tile, for this funnel only.

* **Add button text** — the label shown on a tile before the shopper adds the product to their box. Defaults to "Add to box".
* **Remove button text** — the label shown on a tile after the shopper has added the product. Defaults to "Remove".

Leave either field blank to use your store's translation from the Translations page. If the store translation is also blank, the English default is used.

The unavailable state label ("Unavailable") is not affected by these settings.

To set store-wide defaults for these labels instead of a per-funnel override, go to **Translations** in the Aftersell admin and update the **Add to box** and **Remove from box** entries.

## Shipping

The **Shipping** section sets what the box charges for delivery. The box either ships free or adds a shipping charge. When you charge, you set the amount and choose whether to multiply it by how many items are in the box, so a six-item box can cost six times a per-unit rate or one flat fee.

## Language and order tagging

* **Language** sets the language used for the box copy and buttons, and for product-detail translations.
* **Order tag** applies a Shopify tag to every order that accepts the box. Use it to route fulfillment or to isolate box orders in reporting.

## Limitations

* **One shared accept button.** The box has a single call to action rather than per-product buttons, because Shopify caps how many accepts a post-purchase page can make.
* **No replacement offers.** A box can't be used as a replacement upsell.
* **The price breakdown doesn't collapse.** **Show price breakdown**, under **General settings**, turns it on or off. When it's on it is always expanded — the multi-product offer puts its breakdown behind a "Show price breakdown" link instead.

### Subscription-only products

Products configured to sell only as a subscription (`requiresSellingPlan: true` in Shopify — no one-time purchase option) cannot be included in a build-a-box offer. Every item in a box is charged as a one-time purchase on the order, so Shopify rejects subscription-only products at serve time. These candidates are silently dropped on every real order, even though the funnel editor preview continues to show them.

The funnel editor warns you when this situation is detected:

* **Warning banner** — some candidates are subscription-only but enough non-subscription candidates survive to reach the box minimum. The banner lists the affected products by name. The offer still shows to shoppers, but with fewer products than configured.
* **Critical banner** — all candidates are subscription-only, or the surviving non-subscription candidates cannot reach the box minimum. The offer is skipped entirely for every shopper.

**If you see the warning banner**, the box still works — it just serves fewer products than you configured. Add more candidates that can also be bought once, so the box carries the range you intended.

**If you see the critical banner**, the offer won't run at all until you fix it. Any of these clears it:

* Add candidates that can also be bought once.
* Lower the box minimum, so the surviving candidates are enough to reach it.
* Turn off "subscription only" on the affected products in Shopify, if they should also sell as a one-time purchase.

You can also remove the subscription-only candidates from the box entirely. That changes nothing for shoppers — they're already dropped on every real order — but it silences the banner and makes the editor preview match what actually serves.

Subscription-**enabled** products (those offering both a one-time purchase and a subscription) aren't dropped from a box. They're simply sold as a one-time purchase, like every other box item — a box never carries a selling plan.
