Bundle SDK
Live bundle state and actions for custom storefront UIs. One SDK covers both bundle types: build-your-own bundles and multi-option bundles.
Available after the elite:byob:ready event fires. null when no bundle is on the current page, and the whole sdk object is absent unless SDK access is enabled in Settings → Developer SDK.
const sdk = window.eliteBundle.sdk?.byob;Read the state fresh each time you use it. The object is replaced on every update, so a reference you stashed earlier will go stale.
Both bundle types, one shape
A multi-option bundle is a bundle whose every step holds exactly one item. That is why there is no separate MOB SDK — the same steps, cart and checkout describe both:
steps
the steps the shopper moves through
the options the bundle is built from
cart
everything the shopper picked
one line per option
pick an item
addToCart (adds / increments)
selectOne (replaces that option's pick)
add to cart
checkout()
the theme's own Add to cart button, which the app hooks
Read steps[i].optionMode to tell how an option is filled: "single_product_options" means the shopper builds a variant from one product's own options (Colour → Size); anything else means they pick from a list.
State
bundleId
string — Shopify product ID of the bundle.
steps
Step[] — the configured steps (options, for a multi-option bundle), each with its fetched products.
The quantity limits live under advancedSettings, not on the step itself.
When
showVariantAsIndividualCardis on, each variant is surfaced as its own entry with a syntheticidand a title suffixed by the variant name. UsesourceProductIdwhenever you need the real product.
cart
CartItem[] — the current selection.
cartTotal · cartTotalFormatted · cartCount
number · string · number — the sum of price × quantity, that sum run through the store's money format, and the total item count.
canCheckout
boolean — every requirement is met: the bundle-wide minimum, plus the minimum of each step that has enableSelectionLimit on. Gate your add button on this.
isTierMaxReached
boolean — the cart has reached the highest quantity tier, so there is no further discount to unlock. Only meaningful for quantity-based tiers.
isLoading · error
boolean · string | null — error is a single shopper-facing message; the diagnostic detail goes to the browser console.
isCheckingOut · checkoutError
boolean · string | null — in-flight and failure state for the add to cart.
discountConfig
DiscountSettings — the bundle's discount.
minValue is a count when tierBasedOn is "quantity" and a money amount when it is "order_total". A multi-option bundle's flat discount is expressed as a single tier with minValue: 0, so it always applies.
Actions
formatPrice(amount)
Formats an amount using the store's money format.
addToCart(product, variantId, stepId?)
Adds one unit. stepId defaults to product.stepId.
It can silently do nothing — when the bundle-wide maximum is reached, when the step's own limit is reached, or when the step allows only one of each product and that product is already in. Check canAddToStep(stepId) first if you need to know.
selectOne(product, variantId, stepId?)
Multi-option bundles. Makes this the step's one and only pick, replacing whatever was selected before. Use this rather than addToCart for options — addToCart would leave two items in the same option.
removeFromCart(variantId, stepId?) · updateQuantity(variantId, delta, stepId?)
Remove a line, or change its quantity by delta. A quantity of zero or less removes the line. updateQuantity is subject to the same limits as addToCart and will no-op rather than exceed them.
getItemQuantity(variantId, stepId?)
number — how many of this variant are in the cart.
isStepFull(stepId) · canAddToStep(stepId)
boolean — whether the step has hit its own limit, and whether one more item may be added. canAddToStep also accounts for the bundle-wide maximum, so it can be false even for a step with no limit of its own.
checkout(redirectTarget?)
Adds the whole bundle to the Shopify cart. Only call it when canCheckout is true.
redirectTarget
Behaviour
"stay_on_page" (default)
Stays put and asks the theme to open its cart drawer
"cart"
Redirects to /cart
"checkout"
Redirects to Shopify checkout
On success the bundle is emptied and a new bundle session begins, so a stay_on_page UI must be ready to re-render from an empty cart.
Translated text
title and description are TranslatableString — either a plain string, or { default, translations } when the merchant has translated them. Rendering one directly can print [object Object]:
Full example
See the Events Reference for every event and its payload.
Last updated
Was this helpful?
