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
| Field | Type | Description |
|---|---|---|
packageId | number | Required. Package ref_id from your campaign |
selected | boolean | Add this package to the cart automatically on page load — same effect as data-next-selected="true" on a static card |
quantity | number | Quantity to add when toggling on (default 1); ignored when packageSync is set |
packageSync | string | Comma-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:
| Placeholder | What 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):
| Placeholder | What 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:
| Placeholder | What 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 otherwisedata-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.