Data attributes

Use this page to build a page without writing JavaScript. Mark an element and the SDK wires it up: a card that swaps the cart, an input the order reads, a price that stays in step with the cart. Everything here is drawn from the markup the starter templates actually ship.

How to read this page: sections run in funnel order, and each starts with a minimal skeleton (real template markup stripped to its attributes) showing which attribute sits on which element. The Building Pages guides show the same markup assembled in full, and How it works explains the three kinds of markup these tables mix: activation attributes, display bindings, and template tokens.

Displaying live values

AttributeDescription
data-next-displayReplaces the element's text whenever the value changes
data-next-formatOverrides how that value is written
data-next-showShows the element while a condition is true
data-next-hideHides the element while a condition is true
data-next-awaitHolds children hidden until the SDK's scan finishes

Reach for data-next-display whenever a number or label has to stay in step with the cart or the order. You write no JavaScript: the element's text is replaced every time the value changes.

Use whichever of data-next-show and data-next-hide reads more naturally. data-next-hide="cart.isEmpty" beats data-next-show="!cart.isEmpty". Set one or the other on an element, not both. A condition that fails to parse is logged and the element is left visible, so a typo does not silently hide content.

Example

Below is an example that binds the cart total to a span, shows one block only when the cart has items, hides another when it is empty, and holds a price block invisible until the SDK has finished its scan.

CODE
<span data-next-display="cart.total" data-next-format="currency">$0.00</span>
<div data-next-show="cart.hasItems">You have items in your cart</div>
<div data-next-hide="cart.isEmpty">Ready to check out</div>
<div data-next-await="">
  <span
    data-next-display="bundle.main.price"
    data-next-format="currency"
  ></span>
</div>

Paths and conditions

AttributeDescription
data-next-displayA dotted path, e.g. cart.total
data-next-showA condition, e.g. cart.hasItems
data-next-hideA condition, e.g. param.banner=='n'

A path's first segment names the object it reads from, listed below. The param form reads URL parameters captured at boot.

Formatting

data-next-format defaults to auto, which infers the format from the value and the path: money paths render as currency, booleans as yes/no. Set it only when that inference is wrong.

ValueDescription
autoInfer from the value and the path (the default)
currencyMoney, in the campaign's currency and locale
numberA plain number with locale grouping
percentageA percentage
booleanA true or false value
dateA date
textVerbatim, with no formatting

Inference does not reach bundle.<selectorId>.* bindings written outside a card, so set data-next-format="currency" on those or they render a raw number.

Modifiers

These sit alongside data-next-display and change the value before it is written.

AttributeDescription
data-hide-if-zeroHides a savings row rather than showing $0.00
data-hide-if-falseHides a badge rather than showing No
data-hide-zero-centsWrites $49 instead of $49.00, keeping real cents
data-multiply-byShows a per-unit price as a pack total
data-divide-byShows a per-unit price from a pack total

A discount row that disappears at zero, and a pack price shown per unit.

CODE
<span data-next-display="cart.totalDiscount" data-hide-if-zero="true"></span>
<span
  data-next-display="package.price"
  data-divide-by="3"
  data-hide-zero-cents="true"
></span>

Hiding placeholders until prices load

data-next-await stops visitors seeing - placeholders flash before prices load.

The SDK adds next-display-ready to <html> when its scan finishes. The hiding is done by next-core.css, so the attribute does nothing without that stylesheet on the page.

Display paths

The first segment of a path names one of these objects. The same paths work in data-next-show and data-next-hide conditions.

The cart object

The live cart. Used on Checkout pages.

PathDescription
cart.totalGrand total, after shipping and discounts
cart.subtotalLines before shipping and discounts
cart.shippingShipping charge
cart.totalQuantityUnits in the cart
cart.totalDiscountPercentageDiscount as a share of subtotal

The package object

The loaded campaign. Used on selector and bump cards. The short forms are scoped by the surrounding card's data-next-package-id.

PathDescription
package.nameProduct title
package.imageProduct image URL
package.<refId>.nameTitle of a named package

The bundle object

One bundle selector's calculated pricing. Used for headlines outside the cards, on Checkout and Upsell pages.

PathDescription
bundle.<selectorId>.priceSelected tier's price
bundle.<selectorId>.originalPricePrice before discount
bundle.<selectorId>.discountPercentageDiscount as a percentage

The shipping object

The selected shipping method. Used on Checkout pages.

PathDescription
shipping.isFreeTrue when shipping costs nothing

The param object

URL parameters captured at boot. Used on any page, in conditions.

PathDescription
param.<name>One URL parameter's value

The order object

The completed order, loaded from ?ref_id=. Used on Receipt and Upsell pages.

PathDescription
order.numberConfirmation number
order.totalAmount the customer paid
order.subtotalLines before tax and shipping
order.taxTax charged
order.shippingShipping charged
order.currencyCurrency code
order.paymentMethodHow it was paid, as a name (Credit Card, iDEAL, SEPA Direct Debit) rather than the API's code
order.shippingMethodChosen shipping method
order.customer.nameFull name
order.customer.emailEmail address
order.shippingAddress.line1Street address
order.shippingAddress.line2Apartment or suite
order.shippingAddress.cityCity
order.shippingAddress.stateState or province
order.shippingAddress.postcodePostal code
order.shippingAddress.countryCountry

order.billingAddress.* carries the same fields as order.shippingAddress.*, plus .name.

Bundle selector

One container, one card per tier; clicking a card writes that tier's lines to the cart. Used on checkout pages and, in select mode, on upsell pages. Assembled in full in the Checkout guide:

CODE
<div
  data-next-bundle-selector
  data-next-selector-id="main"
  data-next-selection-mode="swap"
  data-next-include-shipping="true"
  data-next-await=""
>
  <div
    data-next-bundle-card
    data-next-bundle-id="qty-1"
    data-next-bundle-items='[{"packageId":1,"quantity":1}]'
    data-next-selected="true"
    role="button"
  >
    <span data-next-bundle-display="price">-</span>
  </div>
</div>

On the container

AttributeDescription
data-next-bundle-selectorMarks the container
data-next-selector-idNames the selector, e.g. main
data-next-selection-modeswap (default) or select
data-next-include-shippingCard prices include shipping
data-next-bundlesAuto-renders cards from a template

data-next-bundles takes a JSON array of {id,title,imageSrc,items,…} and stamps one card per entry from a single <template>, using {bundle.*} tokens.

CODE
<div
  data-next-bundle-selector
  data-next-selector-id="main"
  data-next-bundles='[{"id":"qty-1","title":"Buy 1","items":[{"packageId":1,"quantity":1}]}]'
>
  <template>
    <div data-next-bundle-card data-next-bundle-id="{bundle.id}">
      {bundle.title}
    </div>
  </template>
</div>

On a card

AttributeDescription
data-next-bundle-cardMarks one selectable tier
data-next-bundle-idNames the card, e.g. qty-2
data-next-bundle-itemsThe card's cart lines, as JSON
data-next-bundle-vouchersCoupon codes, as JSON
data-next-selectedThe card selected on load
data-next-shipping-idPer-card shipping method
data-next-package-idScopes package.* paths in the card
data-next-bundle-displayThe card's calculated pricing

Example

Below is an example that builds a two-for tier: it swaps the cart to that tier on click, prices the card with its own shipping method and a voucher, pre-selects it on load, and renders its discounted price.

CODE
<div
  data-next-bundle-selector
  data-next-selector-id="main"
  data-next-selection-mode="swap"
  data-next-include-shipping="true"
  data-next-await=""
>
  <div
    data-next-bundle-card
    data-next-bundle-id="qty-2"
    data-next-bundle-items='[{"packageId":1,"quantity":2}]'
    data-next-bundle-vouchers='["UP50"]'
    data-next-shipping-id="2"
    data-next-package-id="1"
    data-next-selected="true"
    role="button"
  >
    <span data-next-bundle-display="price">-</span>
  </div>
</div>

Selection mode

Values data-next-selection-mode accepts.

ValueDescription
swapReplaces the previous card's cart lines
selectUpdates the visual state only

swap is the default. Under select, a separate add-to-cart button performs the cart write. A selector inside data-next-upsell-context is forced to select.

Item flags

Set these inside data-next-bundle-items, alongside packageId and quantity.

FlagDescription
"configurable":trueThe shopper picks variants for this item
"noSlot":trueHidden free gift, kept out of the slot list

Voucher codes

A code in data-next-bundle-vouchers is priced into the card and applied when the card is chosen, so the discount shown is the discount charged.

The codes must already exist in the Campaigns App.

Display values

Values data-next-bundle-display accepts. All but hasDiscount write a number into the element.

ValueDescription
priceTotal after every discount
originalPriceCompare-at total, before discounts
unitPricePer-unit price at the card's quantity
originalUnitPricePer-unit compare-at price
discountAmountDiscount the pricing API applied
discountPercentageDiscount as a share of originalPrice
hasDiscountToggles visibility when a discount exists

Quantity stepper

Available from SDK 0.4.18. Put data-next-bundle-qty-for="<selectorId>" on a block outside the cards.

AttributeDescription
data-next-quantity-increasethe plus button
data-next-quantity-decreasethe minus button
data-next-quantity-displaythe readout
data-next-quantitya card, as its starting quantity
data-next-min-quantitya card, as its floor
data-next-max-quantitya card, as its ceiling

The stepper block sits outside the cards and drives the selector named in data-next-bundle-qty-for.

CODE
<div data-next-bundle-qty-for="main">
  <button data-next-quantity-decrease>-</button>
  <span data-next-quantity-display>1</span>
  <button data-next-quantity-increase>+</button>
</div>
<div
  data-next-bundle-card
  data-next-quantity="1"
  data-next-min-quantity="1"
  data-next-max-quantity="5"
></div>

Multi-variant selectors

AttributeDescription
data-next-bundle-slots-forNames the selector the slots belong to
data-next-bundle-slot-template-idThe template stamped per slot
data-next-variant-selectorsWhere the SDK injects the pickers

The slots block names its selector and the template each slot stamps.

CODE
<div
  data-next-bundle-slots-for="main"
  data-next-bundle-slot-template-id="slot-tpl"
>
  <div data-next-variant-selectors></div>
</div>

The SDK injects a native <select data-next-variant-code> into the variant-selectors element.

Checkout form

One <form> owns everything: fields bind to the order by name, payment methods pair a section with a form body, and the SDK manages the named containers. Assembled field group by field group in the Checkout guide:

CODE
<form data-next-checkout="form">
  <input data-next-checkout-field="fname">
  <select data-next-checkout-field="country"></select>
  <input data-next-checkout-field="address1">
  <div data-next-component="location" class="next-hidden">
    <input data-next-checkout-field="city">
  </div>
  <div data-next-checkout-field="cc-number"></div>
  <button type="submit">Complete Order</button>
</form>
AttributeDescription
data-next-checkoutMarks the checkout root, on a real <form>
data-next-checkout-fieldBinds one input to the order
data-next-componentNames a container the SDK manages
data-next-payment-methodOne payment method section
data-next-payment-formThat method's expandable form body
data-next-express-checkoutWhere wallet buttons are injected
data-next-checkout-stepWhere a multi-step form submits next
data-next-step-numberWhich step of a multi-step form this is
data-next-checkout-reviewReads back what an earlier step collected
data-next-couponA coupon entry field

Example

Below is an example that collects a name and a city, reveals the city group once the address is filled, mounts a hosted card field, injects the wallet buttons, takes a coupon, and submits step one of a multi-step flow.

CODE
<form data-next-checkout="form">
  <input data-next-checkout-field="fname">
  <div data-next-component="location" class="next-hidden">
    <input data-next-checkout-field="city">
  </div>
  <div data-next-payment-method="credit">
    <div data-next-payment-form="credit">
      <div data-next-checkout-field="cc-number"></div>
    </div>
  </div>
  <div data-next-express-checkout="container">
    <div data-next-express-checkout="buttons"></div>
  </div>
  <div data-next-coupon="input"></div>
  <form
    data-next-checkout-step="/checkout/payment/"
    data-next-step-number="1"
  ></form>
  <span
    data-next-checkout-review="email"
    data-next-enhancer="checkout-review"
  ></span>
</form>

Field names

The SDK finds inputs by data-next-checkout-field, not by their name attribute, so your markup structure is up to you. The names are fixed.

GroupNames
Contactfname, lname, email, phone
Addresscountry, address1, address2, city, province, postal
Cardcc-number, cvv, exp-month, exp-year
Consentaccepts_marketing

cc-number and cvv are the exception to writing your own inputs. Leave them as empty <div>s and the SDK mounts hosted card fields into them, so no card number passes through your page.

Managed containers

Values data-next-component accepts.

ValueDescription
shipping-formThe shipping field group
shipping-field-rowOne row inside that group
locationThe city, state, and postal group
<method>-errorWhere one method's errors render
<method>-error-textThe error message inside it
express-errorWhere express errors render
express-error-textThe error message inside it
scroll-hintThe scroll affordance

location carries class="next-hidden". The SDK reveals it the moment the street address has a value, and never hides it again.

Payment methods

Values data-next-payment-method and data-next-payment-form both accept. Pair a section with a form body of the same value.

ValueMethodCollects details on your pageExpress button
creditCardyes, in the hosted card fieldsno
paypalPayPalnoyes
apple_payApple Paynoyes, except on Android
google_payGoogle Paynoyes
klarnaKlarnanono
linkLinknoyes
affirmAffirmnono
bancontactBancontactnono
giropayGiropaynono
idealiDEALnono
sepa_debitSEPA Direct Debitnono
sofortSofortnono
swishSwishnono
twintTWINTnono

The card is the only method that collects anything on your page. For every other one, data-next-payment-form can be empty: the form still validates and captures the shopper's details, then the order is created and the shopper is sent to that provider to pay.

Names are written with underscores, and - and any casing are also accepted, so apple_pay and apple-pay select the same method. Two methods are stricter than that. The card answers to credit, which the starter templates carry, and to card_token, the orders API's own name, and to no other spelling. SEPA Direct Debit answers to sepa_debit alone: the platform's payment-methods guide calls the same method sepa_direct, and that name is refused so a page cannot reach the API under two identifiers.

The card is also the one method whose name changes on the way out, to card_token. Every other method goes on the order under the value in the table.

A method the campaign cannot charge is hidden for you. The SDK reads the campaign's available_payment_methods and removes any radio outside that list, because an order naming a method the merchant has not enabled is refused and the shopper meets a dead end. Two exceptions keep that from going wrong: the card is never hidden, since every store takes one, and a campaign that lists no methods at all hides nothing. If a shopper had already picked a method that gets hidden, the first one still on the page is selected instead. The console names what went: Hid payment methods this campaign does not offer.

A value that is not in this table is sent to the orders API under that name, lower-cased with _ for -, rather than treated as a card, so a method the platform adds can be offered before the SDK names it. A misspelling therefore produces a refused order: the console line Payment method "…" is not one the SDK knows names the value, so check for it once after adding a method.

Values data-next-express-checkout accepts.

ValueDescription
containerThe express checkout block
buttonsWhere the SDK injects the wallet buttons

The SDK injects one button per express method the campaign lists, for PayPal, Apple Pay, Google Pay and Link. Apple Pay is left out on Android. paymentConfig.expressCheckout sets the order through methodOrder, and its methods block is read only when the campaign lists no express methods at all.

Link is the one method offered both ways. As an express button it goes straight to Link; as a radio it validates the form and captures the shopper's details first. A page carrying both shows Link twice.

Multi-step checkout

AttributeDescription
data-next-checkout-stepThe next step's URL
data-next-step-number1, 2, and so on

Values data-next-checkout-review accepts.

ValueDescription
emailThe email collected earlier
phoneThe phone number collected earlier
addressThe shipping address collected earlier
shippingMethod.nameThe chosen shipping method

It needs data-next-enhancer="checkout-review" on the same element.

Coupon field

Values data-next-coupon accepts.

ValueDescription
(empty)The container wrapping the whole coupon area
inputThe text input the visitor types into
applyThe apply button
displayThe element listing applied codes
messagesThe element showing success and error text

apply is optional: the first <button> in the container is used when it is absent. These configure the field.

AttributeDescription
data-auto-applyApplies a code as soon as it is entered
data-placeholderThe field's placeholder text
data-button-textThe apply button's label

The container wraps the input, the apply button, and both output areas.

CODE
<div data-next-coupon>
  <input
    data-next-coupon="input"
    data-placeholder="Discount code"
    data-auto-apply="true">
  <button data-next-coupon="apply" data-button-text="Apply">Apply</button>
  <div data-next-coupon="display"></div>
  <div data-next-coupon="messages"></div>
</div>

Order bumps

A checkbox-style add-on inside the checkout form: the whole card toggles its package in and out of the cart. Assembled in the Checkout guide:

CODE
<div data-next-package-toggle data-next-await="">
  <div
    data-next-toggle-card
    data-next-package-id="5"
    data-next-is-upsell="true"
    data-next-package-sync="1"
  >
    <span data-next-toggle-display="price">-</span>
  </div>
</div>

On the container

AttributeDescription
data-next-package-toggleMarks the bump container

On a card

AttributeDescription
data-next-toggle-cardOne toggleable card
data-next-package-idThe package the card adds
data-next-is-upsellReports the line as an upsell
data-next-package-syncMatches quantity to another package
data-next-toggle-displayThe bump's pricing
data-next-toggle-imageSwaps in the package image
data-next-toggle-containerMoves state classes to a wrapper

Clicking anywhere on the card adds or removes its package.

Example

Below is an example that offers a warranty as an order bump: it reports the line as an upsell, keeps its quantity matched to package 1, shows a per-unit price, and puts the selected styling on a wrapper rather than the card.

CODE
<div data-next-package-toggle data-next-await="">
  <div data-next-toggle-container>
    <div
      data-next-toggle-card
      data-next-package-id="7"
      data-next-is-upsell="true"
      data-next-package-sync="1"
    >
      <span data-next-toggle-display="unitPrice">-</span>
      <img data-next-toggle-image alt="">
    </div>
  </div>
</div>

Quantity sync

data-next-package-sync takes one or more package ids, e.g. 1 or 101,102.

It keeps the bump's quantity equal to the combined quantity of those packages' cart lines, so one warranty per bottle stays one warranty per bottle. When every synced package leaves the cart, the bump goes with it.

Display values

Values data-next-toggle-display accepts.

ValueDescription
priceLine total after discounts
originalPriceLine total before discounts
unitPricePer-unit price
originalUnitPricePer-unit price before discounts

The per-unit values stay stable across tiers; the line totals scale with the synced quantity. Pick one style per card rather than mixing them.

State container

data-next-toggle-container goes on an ancestor of the card. It puts the card's state classes on that wrapper instead of the card itself.

Use it when the element you style is not the element you click. The clickable area is always the whole data-next-toggle-card.

Post-purchase upsells

Everything the visitor acts on sits inside the offer wrapper, and the first bundle selector inside it is the one that submits. Assembled in full in the Upsell guide:

CODE
<div data-next-upsell="offer" data-next-await="">
  <div
    data-next-bundle-selector
    data-next-upsell-context
    data-next-selector-id="upsell-bundle"
  >
    <div
      data-next-bundle-card
      data-next-bundle-id="1x"
      data-next-bundle-items='[{"packageId":3,"quantity":1}]'
      data-next-selected="true"
      role="button"
    ></div>
  </div>
  <a data-next-upsell-action="add" href="#">Add To My Order</a>
  <a data-next-upsell-action="skip" href="#">No Thanks</a>
</div>
AttributeDescription
data-next-upsellThe offer wrapper, taking offer
data-next-upsell-actionAccepts or declines the offer
data-next-upsell-contextPuts a bundle selector in select mode

Example

Below is an example that presents one post-purchase offer: a bundle selector in select mode so clicks do not touch the cart, with a link that adds the tier to the paid order and a link that skips it.

CODE
<div data-next-upsell="offer" data-next-await="">
  <div
    data-next-bundle-selector
    data-next-upsell-context
    data-next-selector-id="upsell"
  >
    <div
      data-next-bundle-card
      data-next-bundle-id="1x"
      data-next-selected="true"
    ></div>
  </div>
  <a data-next-upsell-action="add" href="#">Add To My Order</a>
  <a data-next-upsell-action="skip" href="#">No Thanks</a>
</div>

Accepting and declining

Values data-next-upsell-action accepts.

ValueDescription
addSubmits the offer, then goes to the accept URL
skipGoes to the decline URL, order untouched

add submits the first bundle selector inside the wrapper.

Upsell context

data-next-upsell-context goes on a bundle selector shown after checkout. It forces select mode, so clicking a tier stops writing to the cart.

Receipt

The order's lines render from a named <template>; everything else on a receipt is an order.* display binding from the order object above. Assembled in the Receipt guide:

CODE
<template id="order-item-template">
  <div>{item.quantity}x {item.name} {item.lineTotal}</div>
</template>
<div data-item-template-id="order-item-template" data-next-order-items=""></div>
AttributeDescription
data-next-order-itemsRenders the order's lines
data-item-template-idNames the template each line stamps

Each line is one stamp of the named <template>, using {item.*} tokens.

Example

Below is an example that renders the purchased lines: a named template holding the row markup, and a list element that stamps it once per line on the order.

CODE
<template id="order-item-template">
  <div>{item.quantity}x {item.name} {item.lineTotal}</div>
</template>
<div data-item-template-id="order-item-template" data-next-order-items=""></div>

Cart summary

The live totals panel on checkout and upsell pages. The nesting that makes {item.*} work (the summary's own <template> holding a data-summary-lines list with its own <template> per line) is shown in How it works and assembled in full in the Checkout guide.

AttributeDescription
data-next-cart-summaryThe live order summary
data-next-discountsA repeating list of discount rows
data-next-quantityCart-line quantity buttons

data-next-discounts takes offer or voucher. data-next-quantity takes increase or decrease, targeted by a data-package-id on the same element.

Example

Below is an example that renders a live totals panel: one row per cart line with quantity buttons, a list of applied vouchers, and the subtotal, shipping, and grand total beneath them.

CODE
<div data-next-cart-summary>
  <template>
    <div data-summary-lines>
      <template>
        <div data-package-id="{item.packageId}">
          {item.quantity}x {item.name} {item.price}
          <button
            data-next-quantity="decrease"
            data-package-id="{item.packageId}"
          >
            -
          </button>
          <button
            data-next-quantity="increase"
            data-package-id="{item.packageId}"
          >
            +
          </button>
        </div>
      </template>
    </div>
    <ul data-next-discounts="voucher">
      <template><li>{discount.name} {discount.amount}</li></template>
    </ul>
    <div>{subtotal} {shipping} {total}</div>
  </template>
</div>

Summary tokens

The summary's direct <template> is the layout.

TokenDescription
{subtotal}Lines before shipping and discounts
{shipping}Shipping charge
{total}Grand total
{currency}Currency symbol
{discounts}Total discount amount

There is no {tax} summary token.

Cart line tokens

Available inside the data-summary-lines line template.

TokenDescription
{item.quantity}Units on this line
{item.name}Product title
{item.variantName}Variant title
{item.packageId}The line's package id
{item.image}Package image URL
{item.price}Line total after discounts
{item.originalPrice}Line total before discounts
{item.unitPrice}Per-unit price
{item.originalUnitPrice}Per-unit price before discounts
{item.frequency}Subscription frequency label
{item.hasDiscount}show or hide, as a CSS class hook

Discount row tokens

Available inside a data-next-discounts template.

TokenDescription
{discount.name}The discount's name
{discount.amount}Amount taken off
{discount.description}Longer description
{discount.percentage}Discount as a percentage

Order line tokens

Available inside the receipt's order-item-template.

TokenDescription
{item.quantity}Units on this line
{item.name}Product title
{item.image}Package image URL
{item.id}The line's id
{item.lineTotal}Line total

A token only means something inside its owner's <template>. Anywhere else it stays on screen as literal text.

UI helpers

AttributeDescription
data-next-accordionA collapsible section
data-next-tooltipA hover tooltip, taking the text
data-next-actionA buy button that writes to the cart

data-next-action takes add-to-cart, with data-next-package-id naming its target.

CODE
<button data-next-action="add-to-cart" data-next-package-id="1">Buy now</button>

Tooltip options

AttributeDescription
data-next-tooltipThe text to show
data-next-tooltip-placementWhich side it opens on, default top
data-next-tooltip-offsetGap in pixels, default 8
data-next-tooltip-delayDelay in milliseconds before it opens

All four tooltip attributes on one element.

CODE
<span
  data-next-tooltip="Helpful text"
  data-next-tooltip-placement="top"
  data-next-tooltip-offset="8"
  data-next-tooltip-delay="0"
></span>

Accordion parts

data-next-accordion takes a name, e.g. order-summary. These share that name.

AttributeDescription
data-next-accordion-triggerthe clickable header
data-next-accordion-panelthe collapsing body
data-next-accordion-textthe label that swaps

Configure it with data-open-text, data-close-text, data-toggle-class, and data-initial-state. This is the mobile order-summary drawer on every starter checkout.

CODE
<div data-next-accordion="faq1" data-initial-state="closed">
  <button data-next-accordion-trigger="faq1">
    <span data-next-accordion-text="faq1">Show</span>
  </button>
  <div data-next-accordion-panel="faq1">Panel body</div>
</div>

Cautions

  • Use the debugger to find a mistyped attribute. Open the page with ?debugger=true and turn on x-ray mode: every element the SDK enhanced is outlined, so the one that is not outlined is the one with the typo. See Debugger.
  • A mistyped attribute does nothing, silently. The scanner matches exact names; data-next-bundle-card misspelled is inert markup with no warning. When something fails to come alive, diff your attribute spelling against these tables first.
  • Remote bundle.* display bindings need data-next-format. Inside a card, data-next-bundle-display formats itself; outside one, data-next-display="bundle.main.price" renders an unformatted number until you add data-next-format="currency".
  • A display path is not a template token. data-next-display="cart.total" binds an element; {total} works only inside a list feature's <template>. Mixing them leaves a literal {total} on screen or a binding that never fills.
  • The legacy os-* attributes in the starter templates are carryover, not API. They survive only as compatibility fallbacks for old pages and are not documented here. Copy the data-next-* attributes, never the os-* ones.