Next Commerce
Bundle Selector

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:

VariableDescription
{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:

VariableDescription
{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.

VariableDescription
{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:

VariableValuesDescription
{item.hasDiscount}show / hideWhether a discount is applied to this item
{item.currency}ISO 4217 codeCurrency code for this slot's prices (e.g. USD)

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 }
  ]
}

On this page