EventMap

interface EventMap { cart:updated: CartState; cart:item-added: { packageId: number; quantity?: number; source?: string }; cart:item-removed: { packageId: number }; cart:quantity-changed: { packageId: number; quantity: number; oldQuantity: number }; cart:package-swapped: { previousPackageId: number; newPackageId: number; previousItem?: CartItem; newItem?: CartItem; priceDifference: number; source?: string }; campaign:loaded: Campaign; checkout:started: CheckoutData; checkout:form-initialized: { form: HTMLFormElement }; checkout:spreedly-ready: {}; checkout:express-started: { method: 'apple_pay' | 'paypal' | 'google_pay' }; order:completed: Order; order:redirect-missing: { order: any }; error:occurred: ErrorData; currency:fallback: { requested: string; actual: string; reason: 'cached' | 'api' }; timer:expired: { persistenceId: string }; config:updated: ConfigState; coupon:applied: { coupon: AppliedCoupon } | { code: string }; coupon:removed: { code: string }; coupon:validation-failed: { code: string; message: string }; selector:item-selected: { selectorId: string; packageId: number; previousPackageId: number | undefined; mode: string; pendingAction: boolean | undefined; item?: SelectorItem }; selector:action-completed: { selectorId: string; packageId: number; previousPackageId: number | undefined; mode: string }; selector:selection-changed: { selectorId: string; packageId?: number; quantity?: number; item?: SelectorItem }; selector:quantity-changed: { selectorId: string; packageId: number; quantity: number }; shipping:method-selected: { shippingId: string; selectorId: string }; shipping:method-changed: { methodId: number; method: any }; action:success: { action: string; data?: any }; action:failed: { action: string; error: Error }; upsell:accepted: { packageId: number; quantity: number; orderId: string; value?: number; discount?: number; coupon?: string }; upsell-selector:item-selected: { selectorId: string; packageId: number }; upsell:quantity-changed: { selectorId?: string; quantity: number; packageId?: number }; upsell:option-selected: { selectorId: string; packageId: number }; message:displayed: { message: string; type: string }; payment:tokenized: { token: string; pmData: any; paymentMethod: string }; payment:error: { message: string; code?: string; details?: unknown }; checkout:express-completed: { method: string; success: boolean }; checkout:express-failed: { method: string; error: string }; express-checkout:initialized: { method: 'apple_pay' | 'paypal' | 'google_pay' | 'link'; element: HTMLElement }; express-checkout:error: { method: 'apple_pay' | 'paypal' | 'google_pay' | 'link'; error: string }; express-checkout:started: { method: 'apple_pay' | 'paypal' | 'google_pay'; cartTotal: { value: number; formatted: string }; itemCount: number }; express-checkout:failed: { method: 'apple_pay' | 'paypal' | 'google_pay'; error: string }; express-checkout:completed: { method: 'apple_pay' | 'paypal' | 'google_pay'; order: any }; express-checkout:redirect-missing: { order: any }; address:autocomplete-filled: { type: 'shipping' | 'billing'; components: any }; address:location-fields-shown: {}; checkout:location-fields-shown: {}; checkout:billing-location-fields-shown: {}; upsell:initialized: { packageId: number; element: HTMLElement }; upsell:adding: { packageId: number }; upsell:added: { packageId: number; quantity: number; order: any; value?: number; willRedirect?: boolean }; upsell:error: { packageId: number; error: string }; accordion:toggled: { id: string; isOpen: boolean; element: HTMLElement }; accordion:opened: { id: string; element: HTMLElement }; accordion:closed: { id: string; element: HTMLElement }; upsell:skipped: { packageId?: number; orderId?: string }; upsell:viewed: { packageId?: number; pagePath?: string; orderId?: string }; exit-intent:shown: { imageUrl?: string; template?: string }; exit-intent:clicked: { imageUrl?: string; template?: string }; exit-intent:dismissed: { imageUrl?: string; template?: string }; exit-intent:closed: { imageUrl?: string; template?: string }; exit-intent:action: { action: string; couponCode?: string }; sdk:url-parameters-processed: {}; offer:selected: { offerId: number }; offer:applied: { offerId: number }; bundle:selected: { selectorId: string; items: { packageId: number; quantity: number }[] }; bundle:selection-changed: { selectorId: string; items: { packageId: number; quantity: number }[] }; bundle:quantity-changed: { selectorId: string; bundleId: string; quantity: number; items: { packageId: number; quantity: number }[] }; bundle:price-updated: { selectorId: string }; selector:price-updated: { selectorId: string; packageId: number }; toggle:price-updated: { packageId: number }; toggle:toggled: { packageId: number; added: boolean }; toggle:selection-changed: { selected: number[] }; scroll-hint:updated: { isVisible: boolean; scrollTop: number; scrollHeight: number; clientHeight: number }; }

Source: global.ts:19

The complete catalog of events the SDK emits, mapped to their payload shape.

Each key is an event name you can subscribe to (sdk.on('cart:updated', …)), and its value is the object your handler receives. Use this as the lookup for "what fields does this event give me?" — the narrative guide to subscribing lives in the JavaScript API reference.


Properties

cart:updated: CartState

The cart changed and its totals were recalculated. Fires after every add, remove, quantity change, swap, coupon, and shipping change — so it is the one event to bind a cart display to, rather than subscribing to each of those.

The payload is the whole cart, not a delta.

cart:item-added: { packageId: number; quantity?: number; source?: string }

A package was successfully added to the cart.

Properties

  • packageId (number) — The ref_id of the package that was added.
  • quantity (number, optional) — How many units were added.
  • source (string, optional) — Where the package came from: selector when a linked selector supplied it, direct when it came from the button's own data-next-package-id.

Example

CODE
{
  "packageId": 42,
  "quantity": 1,
  "source": "selector"
}

cart:item-removed: { packageId: number }

A line was removed from the cart — by a remove button, or by a quantity control dropping it to zero.

Properties

  • packageId (number) — The package whose line was removed.

Example

CODE
{ "packageId": 42 }

cart:quantity-changed: { packageId: number; quantity: number; oldQuantity: number }

A cart line's quantity changed. Fired after the write succeeds, so the cart store already reflects the new value. Not fired when the requested quantity equals the current one.

Properties

  • packageId (number) — The package whose quantity changed.
  • quantity (number) — The new quantity. 0 means the line was removed from the cart.
  • oldQuantity (number) — The quantity before the change.

Example

CODE
{
  "packageId": 42,
  "quantity": 3,
  "oldQuantity": 2
}

cart:package-swapped: { previousPackageId: number; newPackageId: number; previousItem?: CartItem; newItem?: CartItem; priceDifference: number; source?: string }

One package replaced another in a single operation, keeping the cart at one line instead of removing and adding — which is what a swap-mode selector does when the visitor picks a different card.

Properties

  • previousPackageId (number) — The package that was in the cart before the swap.
  • newPackageId (number) — The package now in the cart.
  • previousItem (CartItem, optional) — The full line as it was before the swap, when it could be resolved.
  • newItem (CartItem, optional) — The full line as it is after the swap.
  • priceDifference (number) — New price minus old price. Negative when the visitor traded down.
  • source (string, optional) — What triggered the swap, e.g. selector.

Example

CODE
{
  "previousPackageId": 101,
  "newPackageId": 102,
  "priceDifference": 10,
  "source": "selector"
}

campaign:loaded: Campaign

deprecated
global.ts:122

Campaign data — packages, currency, and settings — finished loading.

Declared and subscribed to, but never emitted by this build. A handler registered for it will not fire; read `useCampaignStore.getState().data` instead.

checkout:started: CheckoutData

The visitor submitted the checkout form and the order request is about to go out. Fires before the payment call, so the order does not exist yet.

checkout:form-initialized: { form: HTMLFormElement }

The checkout form finished wiring up its fields, validation, and payment.

Properties

  • form (HTMLFormElement) — The form element that was initialized.

checkout:spreedly-ready: {}

The Spreedly card iframe is ready to accept card details.

checkout:express-started: { method: 'apple_pay' | 'paypal' | 'google_pay' }

deprecated
global.ts:142

An express checkout flow started.

Declared but never emitted by this build. Use `express-checkout:initialized`, which is the event the express container actually fires.

Properties

  • method ("apple_pay" | "paypal" | "google_pay")

order:completed: Order

The page is holding a finished order: it was opened with ?ref_id= — a success, receipt or upsell page — and the order came back from the orders API.

This is the event to hang purchase tracking on, and the only one the SDK's own dl_purchase comes from — once per order, see the analytics events reference. The order it carries was fetched back from the API, so it is a real order with a real order number, and for every payment method that finishes at a gateway it is the first point at which the SDK knows the shopper actually paid.

The checkout page does not fire this. Creating an order is not completing one: an express checkout (PayPal, Apple Pay, Google Pay) and a card payment needing 3-D Secure both leave the checkout page with the money still unmoved, the order carrying a payment_complete_url and the shopper redirected to the gateway to finish paying. Reporting a purchase there is issue #71, so nothing is emitted until the shopper lands back on a page that fetches the order. If you need to act the moment an order is created, do it in your own submit handler — the SDK has no event for it.

Fires on a fresh fetch only. A reload inside the order store's 15-minute window is served from its cache and emits nothing.

It fires on a failed payment's landing page too. A redirect payment comes back to either success_url or payment_failed_url and the platform puts ?ref_id= on both, so the order loads either way. The SDK's own dl_purchase tells the two apart; a listener of your own must check for itself — an order still carrying payment_complete_url was never paid.

Example

CODE
window.next.on('order:completed', order => {
  console.log('Thank you for order', order.number);
});

order:redirect-missing: { order: any }

The order succeeded but carried no redirect URL, so the SDK could not send the visitor onward. Handle this to avoid stranding them on the checkout page.

Properties

  • order (any) — The created order, as returned by the API.

error:occurred: ErrorData

Something failed. Emitted both by any feature's error handler and by the central error handler, so one subscriber can watch the whole SDK.

currency:fallback: { requested: string; actual: string; reason: 'cached' | 'api' }

The requested currency was not available for this campaign, so prices are shown in another one. Surface this — otherwise the visitor sees prices in a currency they did not ask for, with no explanation.

Properties

  • requested (string) — The currency that was asked for.
  • actual (string) — The currency actually being used.
  • reason ("cached" | "api") — Where the fallback was decided: cached when a stored campaign supplied it, api when the campaign response did.

Example

CODE
{
  "requested": "CAD",
  "actual": "USD",
  "reason": "api"
}

timer:expired: { persistenceId: string }

A countdown timer reached zero.

Properties

  • persistenceId (string) — The timer's persistence id — the key its deadline is stored under, so the countdown survives a reload. Identifies which timer expired.

Example

CODE
{ "persistenceId": "flash-sale" }

config:updated: ConfigState

deprecated
global.ts:239

SDK configuration changed at runtime.

Declared but never emitted by this build. Read `useConfigStore.getState()` instead.

coupon:applied: { coupon: AppliedCoupon } | { code: string }

A discount code was accepted and applied to the cart. The payload carries the full coupon when the SDK has it, and only the code when it does not.

Example

CODE
{ "code": "SAVE10" }

coupon:removed: { code: string }

A previously applied discount code was taken off the cart.

Properties

  • code (string) — The code that was removed.

coupon:validation-failed: { code: string; message: string }

A discount code was rejected — unknown, expired, or not valid for this cart.

Properties

  • code (string) — The code the visitor entered.
  • message (string) — The reason, already worded for display to the visitor.

Example

CODE
{
  "code": "SAVE10",
  "message": "This code has expired."
}

selector:item-selected: { selectorId: string; packageId: number; previousPackageId: number | undefined; mode: string; pendingAction: boolean | undefined; item?: SelectorItem }

A visitor clicked a card in a selector. Fires after the selection state is updated but before the cart write completes in swap mode.

Properties

  • selectorId (string) — The selector that fired this, matching its data-next-selector-id.
  • packageId (number) — The package on the card the visitor clicked.
  • previousPackageId (number | undefined) — The previously selected package, or undefined if nothing was selected.
  • mode (string) — The selector's mode at click time: swap or select.
  • pendingAction (boolean | undefined) — true in select mode, signalling that an external button still has to perform the cart write.
  • item (SelectorItem, optional) — The full selected item, when the selector could resolve it.

Example

CODE
{
  "selectorId": "main-selector",
  "packageId": 102,
  "previousPackageId": 101,
  "mode": "select",
  "pendingAction": true
}

selector:action-completed: { selectorId: string; packageId: number; previousPackageId: number | undefined; mode: string }

deprecated
global.ts:310

A selector finished the cart write for a pending selection.

Declared but never emitted by this build. Listen for `cart:item-added` or `cart:package-swapped` to know the write landed.

Properties

  • selectorId (string)
  • packageId (number)
  • previousPackageId (number | undefined)
  • mode (string)

selector:selection-changed: { selectorId: string; packageId?: number; quantity?: number; item?: SelectorItem }

The active selection changed. Fires on every selection update — including programmatic ones, such as cart sync auto-selecting an already-in-cart package on load — not only on visitor clicks.

Properties

  • selectorId (string) — The selector that fired this.
  • packageId (number, optional) — The newly selected package.
  • quantity (number, optional) — The quantity currently set on the selected card.
  • item (SelectorItem, optional) — The full selected item, when the selector could resolve it.

Example

CODE
{
  "selectorId": "main-selector",
  "packageId": 101,
  "quantity": 1
}

selector:quantity-changed: { selectorId: string; packageId: number; quantity: number }

A quantity stepper inside a selector card changed that card's quantity. This is the card's own quantity, not a cart line — in select mode nothing has been written to the cart yet.

Properties

  • selectorId (string) — The selector that fired this.
  • packageId (number) — The card whose quantity changed.
  • quantity (number) — The new quantity on that card.

Example

CODE
{
  "selectorId": "main-selector",
  "packageId": 101,
  "quantity": 2
}

shipping:method-selected: { shippingId: string; selectorId: string }

deprecated
global.ts:368

A shipping method was picked in the UI.

Declared but never emitted by this build. Use `shipping:method-changed`, which the cart fires once the method is applied.

Properties

  • shippingId (string)
  • selectorId (string)

shipping:method-changed: { methodId: number; method: any }

The cart's shipping method changed and totals were recalculated.

Properties

  • methodId (number) — The shipping method now applied to the cart.
  • method (any) — The full shipping method record, including its price and label.

Example

CODE
{ "methodId": 5 }

action:success: { action: string; data?: any }

An action feature — an add-to-cart or accept-upsell button — completed its work without throwing. Fires for every such button, so check action to tell which one.

Properties

  • action (string) — Class name of the feature that ran, e.g. AddToCartEnhancer.
  • data (any, optional) — Extra context, including element: the button that was clicked.

Example

CODE
{ "action": "AddToCartEnhancer" }

action:failed: { action: string; error: Error }

An action feature threw while running. The button is re-enabled either way.

Properties

  • action (string) — Class name of the feature that failed, e.g. AddToCartEnhancer.
  • error (Error) — The error that was thrown.

upsell:accepted: { packageId: number; quantity: number; orderId: string; value?: number; discount?: number; coupon?: string }

The visitor accepted a post-purchase upsell and it was added to the existing order. This is the event post-purchase revenue tracking should use — the money is additional to the original order:completed value.

Properties

  • packageId (number) — The upsell package that was added.
  • quantity (number) — How many units were added.
  • orderId (string) — The order the upsell was attached to.
  • value (number, optional) — Item revenue for the accepted line(s), after discounts (post-discount).
  • discount (number, optional) — Total discount applied to the accepted line(s) (pre-discount − value).
  • coupon (string, optional) — Voucher/coupon code applied to the order, when present.

Example

CODE
{
  "packageId": 77,
  "quantity": 1,
  "orderId": "abc123",
  "value": 29.99,
  "discount": 0
}

upsell-selector:item-selected: { selectorId: string; packageId: number }

A card in an upsell offer's built-in selector was chosen.

Properties

  • selectorId (string) — The upsell selector that fired this.
  • packageId (number) — The package on the chosen card.

upsell:quantity-changed: { selectorId?: string; quantity: number; packageId?: number }

The quantity on an upsell offer changed before the visitor accepted it.

Properties

  • selectorId (string, optional) — The upsell selector the offer belongs to. Present whenever the offer has one — whichever control changed the quantity — and absent in direct mode. Before 2026-07-31 a quantity-toggle press sent the key with undefined, so treat "key present but undefined" as direct mode too if you handle events from an older SDK build.
  • quantity (number) — The new quantity.
  • packageId (number, optional) — The package whose quantity changed, when it is known.

upsell:option-selected: { selectorId: string; packageId: number }

An option was chosen inside an upsell offer — a variant or a tier.

Properties

  • selectorId (string) — The upsell selector that fired this.
  • packageId (number) — The package behind the chosen option.

message:displayed: { message: string; type: string }

deprecated
global.ts:476

A message was shown to the visitor.

Declared but never emitted by this build.

Properties

  • message (string)
  • type (string)

payment:tokenized: { token: string; pmData: any; paymentMethod: string }

Card details were exchanged for a payment token. The raw card number never reaches SDK code — only this token does.

Properties

  • token (string) — The payment token to submit with the order.
  • pmData (any) — Payment method metadata returned with the token, e.g. card brand and last four.
  • paymentMethod (string) — Which payment method produced the token.

payment:error: { message: string; code?: string; details?: unknown }

Payment failed. Fires both for card-field errors before submission and for a declined order attempt.

Properties

  • message (string) — The failure, already worded for display to the visitor. When the payment form reported several problems at once they arrive joined into this one string, in the order the form reported them.
  • code (string, optional) — The gateway's response code, when the failure came back from an order attempt.
  • details (unknown, optional) — The raw error response, for logging. Absent for card-field errors.

Example

CODE
{ "message": "Your card was declined.", "code": "gateway_declined" }

checkout:express-completed: { method: string; success: boolean }

deprecated
global.ts:519

An express checkout attempt finished.

Declared but never emitted by this build. Listen for `order:completed`, which fires on the page the shopper lands on afterwards, for express and standard checkout alike.

Properties

  • method (string)
  • success (boolean)

checkout:express-failed: { method: string; error: string }

deprecated
global.ts:526

An express checkout attempt failed.

Declared but never emitted by this build. Listen for `payment:error` or `error:occurred`.

Properties

  • method (string)
  • error (string)

express-checkout:initialized: { method: 'apple_pay' | 'paypal' | 'google_pay' | 'link'; element: HTMLElement }

An express payment button (PayPal, Apple Pay, Google Pay or Link) rendered and is ready to click. Fires once per available method, so a page offering all four sees it four times.

Properties

  • method ("apple_pay" | "paypal" | "google_pay" | "link") — Which express method became available.
  • element (HTMLElement) — The container the button was rendered into.

express-checkout:error: { method: 'apple_pay' | 'paypal' | 'google_pay' | 'link'; error: string }

deprecated
global.ts:546

An express payment method failed to set up.

Declared but never emitted by this build. Listen for `error:occurred`.

Properties

  • method ("apple_pay" | "paypal" | "google_pay" | "link")
  • error (string)

express-checkout:started: { method: 'apple_pay' | 'paypal' | 'google_pay'; cartTotal: { value: number; formatted: string }; itemCount: number }

The visitor started an express checkout — the button was clicked and the SDK is about to ask the orders API for the order.

Remarks

cartTotal is declared but not sent: the emitting call passes method and itemCount only. Read the cart store for the total.

Properties

  • method ("apple_pay" | "paypal" | "google_pay")
  • cartTotal ({ value: number; formatted: string })
  • itemCount (number)

express-checkout:failed: { method: 'apple_pay' | 'paypal' | 'google_pay'; error: string }

An express checkout failed — the order was refused, or the gateway's own fields rejected it. payment:error fires alongside it for the errors that carry payment details.

Properties

  • method ("apple_pay" | "paypal" | "google_pay")
  • error (string)

express-checkout:completed: { method: 'apple_pay' | 'paypal' | 'google_pay'; order: any }

An express checkout produced an order — the orders API accepted it and the SDK is about to redirect the shopper to the payment gateway.

This is not a purchase. The order it carries has a payment_complete_url and no money has moved: the shopper may still cancel at PayPal, or press back. Reporting a conversion here is issue #71 — hang purchase tracking on order:completed instead, which fires on the success page for the finished order.

Remarks

The payload wraps the order: { method, order }, not the order itself.

Properties

  • method ("apple_pay" | "paypal" | "google_pay")
  • order (any)

express-checkout:redirect-missing: { order: any }

deprecated
global.ts:597

An express order carried no redirect URL.

Declared but never emitted by this build. Listen for `order:redirect-missing`.

Properties

  • order (any)

address:autocomplete-filled: { type: 'shipping' | 'billing'; components: any }

The visitor picked a suggested address and the form was filled from it. Fires for either autocomplete provider.

Properties

  • type ("shipping" | "billing") — Which address block was filled.
  • components (any) — The resolved address parts used to fill the fields.

Example

CODE
{ "type": "shipping" }

address:location-fields-shown: {}

deprecated
global.ts:621

Address fields were revealed.

Declared but never emitted by this build. Use `checkout:location-fields-shown`.

checkout:location-fields-shown: {}

The shipping address fields were revealed — the visitor moved past the collapsed autocomplete input, so state, city, and postcode are now on screen.

Also dispatched as a DOM CustomEvent on document, for code that listens outside the SDK: document.addEventListener('checkout:location-fields-shown', …).

checkout:billing-location-fields-shown: {}

The billing address fields were revealed. Also dispatched as a DOM CustomEvent.

upsell:initialized: { packageId: number; element: HTMLElement }

A post-purchase upsell offer was wired up and is on screen.

Properties

  • packageId (number) — The package being offered.
  • element (HTMLElement) — The offer's container element.

upsell:adding: { packageId: number }

The upsell add request went out. Use it to show a pending state.

Properties

  • packageId (number) — The package being added.

upsell:added: { packageId: number; quantity: number; order: any; value?: number; willRedirect?: boolean }

The upsell was added to the order. Fires after the API confirms, and before any redirect to the next offer or the receipt.

Properties

  • packageId (number) — The package that was added.
  • quantity (number) — How many units were added.
  • order (any) — The updated order, as returned by the API.
  • value (number, optional) — Item revenue for the added line, after discounts.
  • willRedirect (boolean, optional) — Whether the SDK is about to navigate away. When true, finish any tracking synchronously — a handler that awaits will not complete.

Example

CODE
{
  "packageId": 77,
  "quantity": 1,
  "value": 29.99,
  "willRedirect": true
}

upsell:error: { packageId: number; error: string }

Adding the upsell failed. The offer stays on screen so the visitor can retry.

Properties

  • packageId (number) — The package that failed to add.
  • error (string) — The failure reason.

accordion:toggled: { id: string; isOpen: boolean; element: HTMLElement }

An accordion section was toggled. Fires for both directions — read isOpen rather than subscribing to the separate opened/closed events.

Properties

  • id (string) — The section's id.
  • isOpen (boolean) — true when the section is now open.
  • element (HTMLElement) — The section element.

accordion:opened: { id: string; element: HTMLElement }

An accordion section opened.

Properties

  • id (string) — The section's id.
  • element (HTMLElement) — The section element.

accordion:closed: { id: string; element: HTMLElement }

An accordion section closed.

Properties

  • id (string) — The section's id.
  • element (HTMLElement) — The section element.

upsell:skipped: { packageId?: number; orderId?: string }

The visitor declined a post-purchase upsell and moved on.

Properties

  • packageId (number, optional) — The package that was declined, when the offer identified one.
  • orderId (string, optional) — The order the offer belonged to.

upsell:viewed: { packageId?: number; pagePath?: string; orderId?: string }

A post-purchase upsell offer became visible to the visitor. Pair it with upsell:accepted and upsell:skipped to measure offer performance.

Properties

  • packageId (number, optional) — The package being offered.
  • pagePath (string, optional) — Path of the page the offer was shown on.
  • orderId (string, optional) — The order the offer belonged to.

exit-intent:shown: { imageUrl?: string; template?: string }

The exit-intent popup was shown — the visitor's pointer left the viewport.

Properties

  • imageUrl (string, optional) — Image the popup was rendered with, when it is image-based.
  • template (string, optional) — Template the popup was rendered from, when it is template-based.

exit-intent:clicked: { imageUrl?: string; template?: string }

The visitor clicked the exit-intent popup's content, rather than dismissing it.

Properties

  • imageUrl (string, optional) — Image the popup was rendered with.
  • template (string, optional) — Template the popup was rendered from.

exit-intent:dismissed: { imageUrl?: string; template?: string }

The popup was dismissed — via the close button, the overlay, or the Escape key. Fires alongside exit-intent:closed.

Properties

  • imageUrl (string, optional) — Image the popup was rendered with.
  • template (string, optional) — Template the popup was rendered from.

exit-intent:closed: { imageUrl?: string; template?: string }

The popup was removed from the page, whatever the reason.

Properties

  • imageUrl (string, optional) — Image the popup was rendered with.
  • template (string, optional) — Template the popup was rendered from.

exit-intent:action: { action: string; couponCode?: string }

The visitor took the popup's offer — usually accepting a discount code.

Properties

  • action (string) — Which action was taken.
  • couponCode (string, optional) — The code the popup applied, when the action carries one.

Example

CODE
{
  "action": "accept",
  "couponCode": "STAY10"
}

sdk:url-parameters-processed: {}

The SDK finished reading campaign parameters off the page URL — currency, forced package, test mode, attribution. Anything that depends on those values should wait for this rather than reading them at load.

offer:selected: { offerId: number }

deprecated
global.ts:795

An offer was selected.

Declared but never emitted by this build. Offers moved to a server-side model and the client-side offer features were removed.

Properties

  • offerId (number)

offer:applied: { offerId: number }

deprecated
global.ts:802

An offer was applied to the cart.

Declared but never emitted by this build. Offers are applied server-side; read the discounts on `cart:updated` instead.

Properties

  • offerId (number)

bundle:selected: { selectorId: string; items: { packageId: number; quantity: number }[] }

A bundle card was chosen. A bundle is several packages bought as one unit, so the payload carries every line the choice implies, not a single package.

Properties

  • selectorId (string) — The bundle selector that fired this.
  • items ({ packageId: number; quantity: number }[]) — Every package the chosen bundle puts in the cart, with quantities.

Example

CODE
{
  "selectorId": "main-bundle",
  "items": [
    { "packageId": 101, "quantity": 2 },
    { "packageId": 105, "quantity": 1 }
  ]
}

bundle:selection-changed: { selectorId: string; items: { packageId: number; quantity: number }[] }

The chosen bundle's contents changed — a different card, a variant swap, or a quantity bump. Fires on every change, including programmatic ones, so it is the event to bind a button or a price display to.

Properties

  • selectorId (string) — The bundle selector that fired this.
  • items ({ packageId: number; quantity: number }[]) — The bundle's packages after the change.

bundle:quantity-changed: { selectorId: string; bundleId: string; quantity: number; items: { packageId: number; quantity: number }[] }

The bundle-level quantity stepper changed, multiplying every line in the bundle.

Properties

  • selectorId (string) — The bundle selector that fired this.
  • bundleId (string) — The bundle whose quantity changed.
  • quantity (number) — The new bundle multiplier.
  • items ({ packageId: number; quantity: number }[]) — The resulting package lines, with the multiplier already applied.

Example

CODE
{
  "selectorId": "main-bundle",
  "bundleId": "starter",
  "quantity": 2,
  "items": [{ "packageId": 101, "quantity": 4 }]
}

bundle:price-updated: { selectorId: string }

Bundle prices finished loading and the price slots were filled.

Delivered as a DOM CustomEvent on document, not through the event bus — subscribe with document.addEventListener('bundle:price-updated', …). next.on() will not receive it.

Properties

  • selectorId (string)

selector:price-updated: { selectorId: string; packageId: number }

One selector card's prices finished loading and its raw data-package-price-* attributes were written.

Delivered as a DOM CustomEvent on document, not through the event bus — subscribe with document.addEventListener('selector:price-updated', …). next.on() will not receive it.

Properties

  • selectorId (string)
  • packageId (number)

toggle:price-updated: { packageId: number }

A package toggle's price finished loading.

Delivered as a DOM CustomEvent on document, not through the event bus.

Properties

  • packageId (number)

toggle:toggled: { packageId: number; added: boolean }

A package toggle was switched — an add-on like a warranty or express shipping going into or out of the cart.

Properties

  • packageId (number) — The package that was toggled.
  • added (boolean) — true when it is now in the cart, false when it was removed.

Example

CODE
{ "packageId": 205, "added": true }

toggle:selection-changed: { selected: number[] }

The full set of toggled-on packages changed.

Properties

  • selected (number[]) — Every package currently toggled on.

scroll-hint:updated: { isVisible: boolean; scrollTop: number; scrollHeight: number; clientHeight: number }

A scroll hint recalculated whether it should be visible — on scroll, and when the scrollable content resizes.

Properties

  • isVisible (boolean) — Whether the hint is showing: the target is at the top and can scroll.
  • scrollTop (number) — Current scroll offset of the watched element.
  • scrollHeight (number) — Full scrollable height of the watched element.
  • clientHeight (number) — Visible height of the watched element.

Example

CODE
{
  "isVisible": true,
  "scrollTop": 0,
  "scrollHeight": 1400,
  "clientHeight": 600
}