Skip to main content
<dkl-order-goal> recomputes its progress on every cart update and emits a single custom event when the cart total crosses a tier boundary. To run your own logic on a tier change, listen for it — see Reacting to changes and the examples on the web component page.

Emits

widgetId. The app block’s idnull on a web component. discountId identifies which order goal a concurrent instance tracks.
discount-kit-live:order-goal:tier-change
CustomEvent
Fired when the cart total crosses a tier boundary. The initial render establishes the baseline silently — the event fires only on a subsequent change, in either direction (unlocking a tier, or dropping below one when items are removed). The detail carries resource:
resource: {
  widgetId: string | null
  widgetType: 'order-goal'
  discountId: string
  previousTier: OrderGoalTier | null
  currentTier: OrderGoalTier | null
  cartTotalCents: number
}

// previousTier / currentTier are null below the first tier
type OrderGoalTier = {
  tierLevel: number
  minSpendCents: number
  discountAmount: number     // raw config value: percent, or CENTS for fixedAmount
  discountType: 'percentage' | 'fixedAmount'
  message: string
}
Note currentTier.discountAmount is the raw config value — a percent, or cents for fixedAmount.
A full example payload — the cart crossing from tier 1 into tier 2:
// event.detail.resource on tier-change
{
  widgetId: 'a1b2c3d4',        // the app block's id (null on a web component)
  widgetType: 'order-goal',
  discountId: 'discount-1478638797012',
  previousTier: {
    tierLevel: 1,
    minSpendCents: 5000,
    discountAmount: 10,
    discountType: 'percentage',
    message: 'Save 10%'
  },
  currentTier: {
    tierLevel: 2,
    minSpendCents: 10000,
    discountAmount: 15,        // percent — or CENTS when discountType is 'fixedAmount'
    discountType: 'percentage',
    message: 'Save 15%'
  },
  cartTotalCents: 11000
}

Lifecycle

Each Order Goal instance also emits mount and unmount events as its behaviour attaches and tears down — handy for wiring up (and cleaning up) custom integrations per instance. Both bubble and carry a DklWidgetEventDetail resource. Order goals are order-level, so the payload is just widgetType and widgetId (no product/variant).
discount-kit-live:widget:mount
CustomEvent
Fired once the controller has attached its behaviour to the (already server-rendered) element, after the baseline tier is established. resource: { widgetType, widgetId }.
discount-kit-live:widget:unmount
CustomEvent
Fired when the instance tears down — e.g. the element is removed, or the theme editor re-renders the section. Same resource shape. Use it to detach any listeners or observers you set up on mount.
// event.detail.resource on widget:mount / widget:unmount
{
  widgetType: 'order-goal',
  widgetId: 'a1b2c3d4'         // the app block's id (null on a web component)
}

Next steps

Web Components

Listener and payload examples for reacting to tier changes.

Order Goal overview

What the component does, and how it reads the cart total.