Accept Button
data-next-action="accept-upsell" activates a button-only enhancer that submits a post-purchase upsell when clicked. It does not render anything — it only manages the button's enabled/disabled state and fires a single API call.
The button is enabled when both of these are true:
orderStore.canAddUpsells()returnstrue(order loaded, supports upsells, no submission in flight)- A package can be resolved (from a direct attribute or a linked selector)
Direct Package
Set data-next-package-id to a fixed package. Use this when the offer never varies.
<button
data-next-action="accept-upsell"
data-next-package-id="42"
data-next-quantity="1"
data-next-url="/upsell-2">
Yes, add to my order
</button>The optional data-next-url overrides the <meta name="next-upsell-accept-url"> redirect for this specific button.
Selector-Driven (Variant Choice)
Pair the button with a PackageSelectorEnhancer running in upsell context. The selector handles the visual choice; the button reads the current selection and submits it.
<div
data-next-package-selector
data-next-selector-id="upsell-pkg"
data-next-upsell-context>
<div data-next-selector-card data-next-package-id="42" data-next-selected="true">
1 bottle — $29
</div>
<div data-next-selector-card data-next-package-id="43">
3 bottles — $69
</div>
</div>
<button
data-next-action="accept-upsell"
data-next-selector-id="upsell-pkg"
data-next-url="/upsell-2">
Add to my order
</button>The data-next-selector-id value must match between the selector container and the button.
data-next-upsell-context on the selector is required. It puts the selector into select mode and disables all cart writes. Without it, clicking a card would write to the cart, which is wrong on a post-purchase page.
Bundle-Driven
Pair the button with a BundleSelectorEnhancer to submit a multi-package bundle as the upsell. Use data-next-upsell-action-for (not data-next-selector-id) to link them.
<div
data-next-bundle-selector
data-next-selector-id="upsell-bundle"
data-next-upsell-context>
<div data-next-bundle-card
data-next-bundle-id="duo"
data-next-bundle-items='[{"packageId":42,"quantity":1},{"packageId":43,"quantity":1}]'
data-next-selected="true">
Duo Pack
</div>
</div>
<button
data-next-action="accept-upsell"
data-next-upsell-action-for="upsell-bundle">
Add bundle to my order
</button>When linked to a bundle, the button submits all items in the selected bundle as a single addUpsell call. One upsell:accepted event is emitted per package.
Programmatic Submission
The enhancer exposes triggerAcceptUpsell() on the bound element. This goes through the same path as a real click — duplicate detection, redirect, and all.
const button = document.querySelector('[data-next-action="accept-upsell"]');
await button.triggerAcceptUpsell();triggerAcceptUpsell() is only available after the SDK has initialized the button. Call it after next:initialized or in a nextReady callback.
Duplicate Detection
If the customer has already accepted the same package in this session, clicking the button shows a confirmation dialog before re-submitting. "Yes, add again" submits a second time; "Skip to next" navigates to the decline URL without submitting.
Duplicates are tracked in orderStore.completedUpsells and orderStore.upsellJourney. The state persists across pages (sessionStorage), so the dialog will appear if the customer hits Back and clicks the same button again.
bfcache Recovery
When the customer navigates away and presses the browser Back button, the page may be restored from the back/forward cache. In that case the loading overlay from the previous click is cleared and the button is re-enabled automatically — the customer is never stuck on a "loading" state from a stale click.
Conflicts
- Do not put
data-next-action="add-to-cart"on the same button.add-to-cartwrites to the cart store;accept-upsellwrites to the order API. They are independent stores and writing to both for the same item produces duplicate records. - Do not pair the accept button with a
CartToggleEnhancerfor the same package on a post-purchase page — same conflict as above. - For variant choice on an upsell page, always use a
PackageSelectorEnhancerwithdata-next-upsell-context. Do not use a regular package selector — it will write to the cart.
Next Steps
- The container-based alternative: Offer Container
- All accept-button attributes: Reference → Attributes
- Events emitted on accept: Reference → Events