JavaScript API
Everything a trigger element can do, code can do too. The Discount Kit Live app embed
defines a global window.DiscountKitLive synchronously on every page, so the quickview can
be opened from any script — with or without a <dkl-quickview> tag on the page. The dialog’s
bundle is loaded lazily on first use.
DiscountKitLive.openQuickview(options)
Section titled “DiscountKitLive.openQuickview(options)”Opens the dialog and returns a promise that resolves once the product has loaded and rendered, or rejects if the bundle fails to load, the product isn’t found, or the dialog is closed (or superseded by another open) before the product arrives.
try { const { panel, productHandle, productId } = await window.DiscountKitLive.openQuickview({ productHandle: 'awesome-tee', variantId: 41200000000001, }) // panel === 'product': the product is loaded and rendered} catch (err) { // bundle failed to load, product not found, or closed before load}Options
Section titled “Options”The same fields as the trigger’s data-* attributes (see
Styling & Data Attributes), in camelCase:
productHandle
Section titled “productHandle”string
The product to load. Provide this or productId.
productId
Section titled “productId”string | number
Product id (numeric or gid://shopify/Product/…) as a stable alternative to the handle.
Resolved through the Storefront API source; pair it with a handle on the Ajax fallback.
variantId
Section titled “variantId”number · default: (first available)
Variant to preselect once the product loads.
products
Section titled “products”Array<{ productHandle?, productId?, variantId? }>
Two or more products open the product picker first. Every other option applies to
whichever product the shopper picks — including a top-level variantId, which preselects on
any choice that doesn’t set its own. Give each choice its own productHandle or productId
rather than relying on the top-level ones, which are also inherited by a choice that omits
them. See Multiple products.
pickerHeading / optionsHeading
Section titled “pickerHeading / optionsHeading”string · defaults: Choose a product / Choose your options
Custom header headings for the picker and options screens. optionsHeading also fills the
otherwise-empty header on single-product opens.
closeOnAdd
Section titled “closeOnAdd”boolean · default: false
Close the dialog after a successful add-to-cart.
showQty
Section titled “showQty”boolean · default: true
Show the quantity stepper. When false, the preset qty is what gets added.
qty / minQty / maxQty
Section titled “qty / minQty / maxQty”number · defaults: minQty / 1 / unlimited
Preset quantity and its bounds. qty is clamped into [minQty, maxQty] and applies even
when the stepper is hidden.
allowQtyChange
Section titled “allowQtyChange”boolean · default: true
When false, the stepper is shown but inert — the preset qty is what gets added.
lineProperties
Section titled “lineProperties”Record<string, string>
Line-item properties attached to every cart add from this open, e.g.
{ '_dkl.source': 'quickview' }. Prefix a key with _ to keep it hidden in most themes’
cart display.
showBadge / showVolume
Section titled “showBadge / showVolume”boolean · default: true
Mount the product’s Discount Badge /
Volume Picker inside the dialog. Nothing renders
when the product has no eligible discount; set false to opt out.
moneyFormat
Section titled “moneyFormat”string · default: shop money format
Money format string for price rendering.
Result
Section titled “Result”The promise resolves with:
{ panel: 'product' | 'products', // 'products' = the picker rendered, nothing chosen yet productHandle: string | null, // null on the picker productId: number | null, // null on the picker}Multiple products
Section titled “Multiple products”await window.DiscountKitLive.openQuickview({ products: [ { productHandle: 'awesome-tee' }, { productHandle: 'awesome-hoodie', variantId: 41200000000456 }, // per-choice preselect { productId: 9265883611348 }, ], pickerHeading: 'Choose your free gift', optionsHeading: 'Choose your size', closeOnAdd: true,})// Resolves with panel: 'products' once the picker rendersDiscountKitLive.closeQuickview()
Section titled “DiscountKitLive.closeQuickview()”Closes the dialog. A no-op if nothing is open (or the bundle was never loaded).
Per-element methods and the open attribute
Section titled “Per-element methods and the open attribute”Every attached <dkl-quickview> trigger gains two methods that open and close its
product:
const trigger = document.querySelector('dkl-quickview[data-product-handle="awesome-tee"]')trigger.openQuickview()trigger.closeQuickview()The open attribute does the same declaratively — add it to open, remove it to close. It’s
also reflected while that trigger’s dialog is open, so you can observe it:
<dkl-quickview data-product-handle="awesome-tee" open> <button type="button">Quick view</button></dkl-quickview>Command events
Section titled “Command events”If you’d rather not hold a reference to anything, dispatch a bubbling event from document
or any element. These are fire-and-forget — there’s no promise — but they work from anywhere,
including pages with no <dkl-quickview> tag (the runtime lazy-loads the dialog for you):
document.dispatchEvent(new CustomEvent('discount-kit-live:quickview:open', { detail: { resource: { productHandle: 'awesome-tee', variantId: 41200000000001 } },}))
document.dispatchEvent(new CustomEvent('discount-kit-live:quickview:close'))resource accepts every field of openQuickview(), including products.
Prefer the helper when you need the result; use the event when you just need it to happen.
Labels & translations
Section titled “Labels & translations”The dialog’s text defaults to English. Override any subset globally by setting
window.DklContext.quickviewLabels — for instance from your theme’s layout, so it’s in place
before the dialog first opens:
<script> window.DklContext = { ...window.DklContext, quickviewLabels: { addToCart: {{ 'products.product.add_to_cart' | t | json }}, close: {{ 'accessibility.close' | t | json }}, }, }</script>| Key | Default | Where |
|---|---|---|
dialogLabel |
Quick view |
The dialog’s accessible name |
close |
Close |
Close button |
back |
Back |
Back-to-picker button |
loading |
Loading product… |
Loading state |
addToCart |
Add to cart |
Add-to-cart button |
adding |
Adding… |
Add-to-cart button, in flight |
added |
Added to cart |
Add-to-cart button, after a successful add |
unavailable |
Unavailable |
Add-to-cart button, no such variant |
soldOut |
Sold out |
Add-to-cart button, sold-out variant |
viewDetails |
View full details |
Link to the product page |
quantity |
Quantity |
Stepper label |
decreaseQuantity |
Decrease quantity |
Stepper − button |
increaseQuantity |
Increase quantity |
Stepper + button |
error |
Something went wrong. Please try again. |
Error message |
from |
From |
Price-range prefix (multi-product cards, high-variant fallbacks) |
chooseProduct |
Choose a product |
Picker screen heading |
chooseOptions |
Choose your options |
Options screen heading |
volumeHeading |
Buy [tier_qty]+ |
In-dialog volume picker tier heading |
volumeUnit |
/ea |
In-dialog volume picker unit label |
volumeDiscountLabel |
off each item |
In-dialog volume picker discount label |
volumeUnavailable |
No discount available |
In-dialog volume picker unavailable label |
badgeLabel |
Save up to [amount] |
In-dialog discount badge label |
Per-open headings (pickerHeading / optionsHeading, or the data-*-heading attributes)
win over chooseProduct / chooseOptions.