Next Commerce
Addon Toggle

Card Templates

Instead of writing a separate HTML card for each add-on, you can give the toggle a list of packages and one reusable card template. The toggle creates a card for each package in the list, filling in the details automatically.

Use card templates when your add-ons are set up in campaign configuration and you do not want to write a separate HTML card for each one.

<!-- The container holds the package list and points to the template -->
<div data-next-package-toggle
     data-next-packages='[
       {"packageId": 201, "label": "2-Year Warranty"},
       {"packageId": 202, "label": "Shipping Insurance", "selected": true}
     ]'
     data-next-toggle-template-id="toggle-tpl">
</div>

<!-- The template is invisible and reused for each package -->
<template id="toggle-tpl">
  <div data-next-toggle-card
       data-add-text="Add {toggle.label}"
       data-remove-text="✓ {toggle.label} Added">
    <strong>{toggle.label}</strong>
    <span data-next-toggle-display="price"></span>
    <del data-next-toggle-display="originalPrice"></del>
  </div>
</template>

The Package List

data-next-packages holds a list of packages in JSON format. Each entry needs at least a packageId — the ref_id of the package from your campaign.

The smallest possible list:

[{ "packageId": 201 }]

A list with extra fields:

[
  { "packageId": 201, "label": "2-Year Warranty" },
  { "packageId": 202, "label": "Shipping Insurance", "selected": true }
]

Reserved fields

FieldTypeDescription
packageIdnumberRequired. Package ref_id from your campaign
selectedbooleanAdd this package to the cart automatically on page load — same effect as data-next-selected="true" on a static card
quantitynumberQuantity to add when toggling on (default 1); ignored when packageSync is set
packageSyncstringComma-separated list of package IDs — quantity mirrors the sum of those packages in the cart. Same effect as data-next-package-sync on a static card

Any extra fields you add (like label below) become available as {toggle.<fieldName>} placeholders in the template. For example, {"label": "Warranty"} becomes {toggle.label} in the card.

Example with all reserved fields

[
  { "packageId": 201, "label": "2-Year Warranty", "selected": true },
  { "packageId": 202, "label": "Shipping Insurance", "quantity": 2 },
  { "packageId": 203, "label": "Extended Coverage", "packageSync": "10,11,12" }
]

Template Placeholders

Use {toggle.<name>} anywhere in your template HTML to insert a value.

Your custom fields:

Any field you include in the package list entry is available as a placeholder. For example, {"label": "Warranty", "description": "Full coverage"} gives you {toggle.label} and {toggle.description}.

Fields filled in automatically from the campaign:

PlaceholderWhat it shows
{toggle.packageId}Package ref_id
{toggle.name}Package name
{toggle.image}Package image URL
{toggle.quantity}Package quantity
{toggle.productId}Product ID
{toggle.productName}Product name
{toggle.variantName}Product variant name
{toggle.variantId}Product variant ID
{toggle.sku}Product SKU

Price fields (estimated values from campaign data):

PlaceholderWhat it shows
{toggle.price}Formatted total price
{toggle.unitPrice}Formatted per-unit price
{toggle.originalPrice}Retail / compare-at total price
{toggle.originalUnitPrice}Retail / compare-at per-unit price
{toggle.discountAmount}Savings amount (empty when no discount)
{toggle.discountPercentage}Discount percentage (e.g. 20.00%)
{toggle.hasDiscount}"true" / "false"
{toggle.recurringPrice}Recurring charge total
{toggle.originalRecurringPrice}Original recurring price before discounts
{toggle.isRecurring}"true" / "false" — whether the package bills on a recurring schedule
{toggle.interval}Billing interval: "day" or "month" (empty for one-time)
{toggle.intervalCount}Number of intervals between billing cycles (empty for one-time)
{toggle.frequency}Human-readable cadence: "Per month", "Every 3 months", "One time"
{toggle.currency}ISO 4217 currency code

Selection state:

PlaceholderWhat it shows
{toggle.isSelected}"true" / "false" — whether the package is in the cart

Price placeholders show estimated values when the card first appears. For live prices that update as the cart changes, use data-next-toggle-display fields inside the card — see Displaying Prices.


Embedding the Template in the Attribute

If the template is very short, you can write it directly in the attribute instead of using a separate <template> element:

<div data-next-package-toggle
     data-next-packages='[{"packageId":201,"label":"Warranty"}]'
     data-next-toggle-template='<div data-next-toggle-card><strong>{toggle.label}</strong><span data-next-toggle-display="price"></span></div>'>
</div>

For most cases, use the <template> element approach. The inline attribute is only practical for very short one-line cards.


Conditional Display in Templates

Use data-next-show and data-next-hide on elements inside a card template to show or hide content based on the card's data.

  • data-next-show="hasDiscount" — visible when the item has a discount, hidden otherwise
  • data-next-hide="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="toggle-tpl">
  <div data-next-toggle-card
       data-add-text="Add {toggle.label}"
       data-remove-text="Remove {toggle.label}">
    <strong>{toggle.label}</strong>
    <span data-next-toggle-display="price"></span>

    <div data-next-show="hasDiscount">
      Save {toggle.discountPercentage}!
      <del data-next-toggle-display="originalPrice"></del>
    </div>

    <div data-next-show="isRecurring">
      Billed {toggle.frequency} — <span data-next-toggle-display="recurringPrice"></span>
    </div>

    <div data-next-hide="isRecurring">
      One-time purchase
    </div>
  </div>
</template>

Any data-next-show / data-next-hide value that matches a template variable (e.g. hasDiscount, isRecurring, isSelected) is evaluated when the card is created. Store-based conditions like data-next-show="cart.itemCount > 0" still work inside card templates — they are handled by the global Conditional Display system after the card enters the page.

On this page