Skip to content
Docs
Available on the Shopify App Store

Events

<dkl-price> is event-driven. It has no direct reference to the volume picker — instead it listens for the picker’s tier-change event and the theme’s variant-change events, and updates the price accordingly.

discount-kit-live:volume-discount:tier-change

Section titled “discount-kit-live:volume-discount:tier-change”

CustomEvent

Emitted by the volume picker. Matched by product id — a selected tier shows the discounted price, a null tier reverts to base. Coupling is by event name and product id only, with no import between the two components.

Honours the event’s updatesPrice flag: if the picker’s “Update price when a tier is selected” setting is off, <dkl-price> ignores the tier for pricing (the event still fires for other listeners).

It also reacts to the host theme’s variant-change events: on a variant change it updates the base price and re-applies the active tier, recomputing the discount off the new variant’s price (sale-priced variants included).

<dkl-price> emits a price-change event whenever its displayed price updates, plus mount / unmount lifecycle events. All bubble, so you can listen on document.

CustomEvent

Fired whenever the displayed price changes — when a volume tier is selected or deselected, or the variant changes. Not fired on initial mount (the server-rendered price is already in the DOM), and deduped — a recompute that lands on the same price (e.g. switching to an equally-priced variant) doesn’t fire. The detail carries resource with the previous and new price, mirroring the tier event’s previousTier / currentTier:

resource: {
widgetType: 'price'
widgetId: string | null
productId: number | null
variantId: number | null
previousPrice: PriceState | null // null on the first change after mount
currentPrice: PriceState
}
type PriceState = {
priceCents: number // displayed price (discounted when a tier is active)
compareAtCents: number | null // the struck-through "before" price, or null
discounted: boolean // whether a volume tier is applied
tier: VolumeDiscountTier | null // the active tier, or null
}
// VolumeDiscountTier: { index, quantity, discountAmount, discountType, unitPriceCents }

A full example payload — selecting a tier that moves the price from £20.00 to £18.00:

// event.detail.resource on price:change
{
widgetType: 'price',
widgetId: 'a1b2c3d4', // the app block's id (null on a web component)
productId: 7820000000001,
variantId: 41200000000001, // the current variant — updates on a variant change
previousPrice: {
priceCents: 2000,
compareAtCents: null,
discounted: false,
tier: null
},
currentPrice: {
priceCents: 1800,
compareAtCents: 2000, // the original price, now struck through
discounted: true,
tier: {
index: 1,
quantity: 3,
discountAmount: 10,
discountType: 'percentage',
unitPriceCents: 1800
}
}
}

The mount / unmount events fire as the instance’s behaviour attaches and tears down — handy for wiring up (and cleaning up) custom integrations per instance. Both carry a DklWidgetEventDetail resource.

CustomEvent

Fired once the controller has attached its behaviour to the (already server-rendered) element. resource: { widgetType, widgetId, productId?, variantId? }productId and variantId are included when known.

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: 'price',
widgetId: 'a1b2c3d4', // the app block's id (null on a web component)
productId: 7820000000001,
variantId: 41200000000001
}