Slot Templates
Add data-next-bundle-slot-template-id to the container and place a [data-next-bundle-slots] placeholder inside each card to render one row per bundle item with variant selectors.
<div data-next-bundle-selector
data-next-bundle-slot-template-id="slot-tpl">
<div data-next-bundle-card
data-next-bundle-id="duo"
data-next-bundle-items='[{"packageId":10,"quantity":1},{"packageId":20,"quantity":1}]'>
<h3>Duo Bundle</h3>
<div data-next-bundle-slots></div>
<p>Total: <span data-next-bundle-display="price"></span></p>
</div>
</div>
<template id="slot-tpl">
<div class="slot-row">
<img src="{item.image}" alt="{item.name}" />
<strong>{item.name}</strong>
<span>{item.price}</span>
</div>
</template>Slot Template Variables
Slot position:
| Variable | Description |
|---|---|
{slot.index} | 1-based slot number |
{slot.unitNumber} | 1-based unit index within a configurable item |
{slot.unitIndex} | 0-based unit index within a configurable item |
Package identity:
| Variable | Description |
|---|---|
{item.packageId} | Package ID |
{item.name} | Package name |
{item.image} | Package image URL |
{item.quantity} | Quantity for this slot (number of units added to cart) |
{item.variantName} | Variant display name (e.g. "Black / Small") |
{item.productName} | Product name |
{item.sku} | Product SKU |
{item.isRecurring} | "true" / "false" |
Prices:
All values are pre-formatted currency strings (e.g. $10.00). {item.price} is the per-slot total — for a slot with quantity: 3, it is three times the unit price. Use {item.unitPrice} for the single-unit price. Currency is determined by the code returned from the bundle price fetch API; before the first fetch, the campaign's active currency is used.
| Variable | Description |
|---|---|
{item.price} | Slot price after discounts |
{item.originalPrice} | Slot price before discounts |
{item.unitPrice} | Single-unit price after discounts |
{item.originalUnitPrice} | Single-unit price before discounts |
{item.discountAmount} | Slot discount amount |
{item.discountPercentage} | Discount percentage (e.g. 20.00%) |
{item.recurringPrice} | Recurring slot price |
{item.originalRecurringPrice} | Recurring slot price before discounts |
{item.interval} | Billing interval — "day", "week", "month", or "" for one-time |
{item.intervalCount} | Intervals between billing cycles (e.g. 3), or "" for one-time |
{item.frequency} | Human-readable billing frequency (e.g. "Every 3 months", "One time") |
Conditional helpers:
| Variable | Values | Description |
|---|---|---|
{item.hasDiscount} | show / hide | Whether a discount is applied to this item |
{item.isRecurring} | true / false | Whether the item has recurring billing |
{item.currency} | ISO 4217 code | Currency code for this slot's prices (e.g. USD) |
Conditional Display in Slots
Use data-next-show and data-next-hide on elements inside a slot template to toggle visibility based on slot variables.
data-next-show="item.hasDiscount"— visible when the item has a discount, hidden otherwisedata-next-hide="item.isRecurring"— hidden when the item is recurring, visible otherwise
Truthy values: "show", "true", or any non-empty string that is not "hide" or "false".
<template id="slot-tpl">
<div class="slot-row">
<img src="{item.image}" alt="{item.name}" />
<strong>{item.name}</strong>
<span>{item.price}</span>
<div data-next-show="item.hasDiscount">
Save {item.discountPercentage}!
<del>{item.originalPrice}</del>
</div>
<div data-next-show="item.isRecurring">
Billed {item.frequency} — {item.recurringPrice}
</div>
<div data-next-hide="item.isRecurring">
One-time purchase
</div>
</div>
</template>Any data-next-show / data-next-hide value that matches a slot variable (e.g. item.*, slot.*) is evaluated locally at render time. Store-based conditions like data-next-show="cart.itemCount > 0" still work inside slot templates — they are handled by the global ConditionalDisplayEnhancer after the slot enters the DOM.
Per-Slot Discount List
Place a data-next-discounts container inside the slot template to render discounts applied to each individual package in the bundle.
<template id="slot-tpl">
<div class="slot-row">
<img src="{item.image}" alt="{item.name}" />
<strong>{item.name}</strong>
<span>{item.price}</span>
<div data-next-discounts>
<template>
<span class="badge">{discount.name}: -{discount.amount}</span>
</template>
</div>
</div>
</template>Discount row tokens
| Token | Description |
|---|---|
{discount.name} | Discount or offer name |
{discount.amount} | Formatted discount amount (e.g. "$10.00") |
{discount.description} | Human-readable description; empty when absent |
State classes
| Class | When |
|---|---|
next-discounts-empty | No discounts for this slot |
next-discounts-has-items | One or more discounts |
Per-slot discounts come from the per-line breakdown in the bundle price calculation. They are populated after each price fetch and cleared when the bundle is deselected.
The offer/voucher filter (data-next-discounts="offer" / ="voucher") is not available at slot level — per-line discounts from the API are not split by type. Use the unfiltered data-next-discounts attribute.
External Slot Rendering
Use data-next-bundle-slots-for on an element outside the selector container to receive the slot rows for the currently selected bundle. The value must match data-next-selector-id on the container.
<div data-next-bundle-selector data-next-selector-id="my-selector" ...>
<!-- bundle cards -->
</div>
<!-- Slots rendered here, outside the selector -->
<div data-next-bundle-slots-for="my-selector"></div>Per-Unit Configuration (Configurable Items)
By default, a quantity-3 item renders as a single slot. Add "configurable": true to expand it into individual per-unit slots — one per unit — each with its own variant selectors.
[
{
"id": "pick3",
"name": "Pick Your 3",
"items": [
{ "packageId": 101, "quantity": 3, "configurable": true }
]
}
]This renders three slot rows, each with independent variant dropdowns. The cart is updated with the aggregated package quantities after all selections.
Silent Add-Ons (noSlot)
Set "noSlot": true on any bundle item to suppress its slot row. Useful for free gifts or invisible add-ons you want to include in the cart but not show in the slot list.
{
"id": "premium",
"items": [
{ "packageId": 10, "quantity": 1 },
{ "packageId": 99, "quantity": 1, "noSlot": true }
]
}