01 · Availability
Support-enabled, not self-service
The Only Bundles SDK is in limited release. It is enabled by the Only Bundles support team for an approved Product Page Bundle and delivered through the installed Shopify theme app extension. Use the support option on the Only Bundles Shopify listing to request access.
02 · Prerequisites
What must already be in place
- An installed Only Bundles app and a synchronized Product Page Bundle.
- An Online Store 2.0 theme with the Only Bundles product-page app block placed on the bundle product template.
- SDK access enabled by support for that bundle.
- Your custom storefront script loaded early enough to register event listeners before the SDK becomes ready.
03 · Initialization
Listen before you render
The extension parses the synchronized schema-v3 bundle snapshot, applies the active Shopify locale, checks offer eligibility, and hydrates current products and variants from Shopify's Storefront API. Only then does it expose window.WolfpackBundles and dispatch wbp:ready.
const root = document.querySelector('[data-custom-bundle]');
window.addEventListener('wbp:ready', () => {
const { steps, selections } = window.WolfpackBundles.state;
root.replaceChildren();
for (const step of steps) {
const heading = document.createElement('h2');
heading.textContent = step.name;
root.append(heading);
for (const product of step.products) {
const button = document.createElement('button');
button.type = 'button';
button.textContent = `Add ${product.title}`;
button.addEventListener('click', () => {
const result = window.WolfpackBundles.addItem(step.id, product.variantId, 1);
if (!result.success) console.warn(result.error);
});
root.append(button);
}
console.log('Current selection', selections[step.id] || {});
}
});
window.addEventListener('wbp:init-failed', (event) => {
console.error(event.detail.code, event.detail.message);
});04 · State
A read-only snapshot
WolfpackBundles.state returns immutable configuration data and a copied selection map. Read a fresh snapshot after a mutation event; changing a returned object does not change SDK state.
isReadyTrue only after hydration succeeds.bundleIdSynchronized bundle identifier.bundleNameMerchant-configured name.stepsLocalized steps with hydrated products.selectionsstepId → variantId → quantity.discountConfigurationConfigured pricing rules.Hydrated products include IDs, title, image, descriptions, price and compare-at price in cents, availability, inventory quantity, normalized gram weight, options, and variants. Variants include their Shopify ID, title, prices, availability, inventory state, normalized weight, image, and selected options.
05 · Methods
Public methods
addItem(stepId, variantId, quantity)
Adds a positive integer quantity of a known, available hydrated variant. Invalid quantities, unavailable variants, unknown variants, per-product limits, and rule-breaking increases return { success: false, error } without changing state.
removeItem(stepId, variantId, quantity)
Removes a positive integer quantity from a selected variant and deletes the selection when it reaches zero.
clearStep(stepId)
Clears selections for a known step.
validateStep(stepId)
Validates quantity, amount, weight, or category rules with current hydrated variant metrics.
validateBundle()
Returns { valid, errors } for required steps. Default and free-gift steps do not block completion.
getDisplayPrice()
Returns the current subtotal, discounted total, savings, percentage, and formatted display total.
addBundleToCart()
Validates, obtains a signed Cart Transform runtime token, and submits the selected component variants to Shopify's Ajax cart.
06 · Events
Window event reference
| Event | Detail |
|---|---|
wbp:ready | { bundleId, steps } |
wbp:init-failed | { code, message } |
wbp:item-added | { stepId, variantId, quantity } |
wbp:item-removed | { stepId, variantId, quantity } |
wbp:step-cleared | { stepId } |
wbp:discount-tier-reached | { bundleId, tierId, tierIndex, tierCount, feedbackState } |
wbp:cart-success | { bundleId } |
wbp:cart-failed | { error } |
07 · Pricing
Display cents, checkout authority
getDisplayPrice() uses hydrated Shopify variant prices and current Only Bundles rules. original, discounted, and savings are integer cents. The formatted string is for display. Shopify cart and checkout remain authoritative.
08 · Cart handling
Wait for the result event
addBundleToCart() does not redirect. Listen for wbp:cart-success to refresh your theme cart drawer or navigate, and for wbp:cart-failed to show a recoverable error. Never build your own bundle authorization fields or bypass the SDK's runtime-token request.
09 · Debugging
Inspect events locally
Add ?wbp_debug=true to the product-page URL to log SDK state and events in the browser console. Confirm the served storefront build with window.__BUNDLE_WIDGET_VERSION__ after a cache-bypassed reload.
10 · Errors
Initialization fails closed
Technical initialization failures dispatch wbp:init-failed with one of these stable codes:
INVALID_CONFIGURATION— the synchronized snapshot is missing or invalid.MISSING_STOREFRONT_RUNTIME— Shopify Storefront API configuration is unavailable.PRODUCT_HYDRATION_FAILED— current Shopify catalog data could not be loaded.
An ineligible offer remains silently hidden and does not expose the SDK global.
11 · Limitations
Current release boundary
- Product Page Bundles only; Full Page Bundles are not supported.
- Online Store 2.0 themes only; Hydrogen and other headless storefronts are not supported.
- Load one SDK bundle per page.
- There is no npm or public CDN distribution.
- Bundle creation, synchronization, gifts, add-ons, and Admin configuration stay in Only Bundles.
12 · Launch checklist
Verify the real Shopify path
- Ask Only Bundles support to enable SDK access.
- Synchronize the Product Page Bundle and place its app block.
- Register
wbp:readyandwbp:init-failedlisteners before initialization. - Render only hydrated products and variants from SDK state.
- Handle every unsuccessful mutation result without assuming state changed.
- Test quantity, amount, weight, and category rules on desktop and mobile.
- Verify price, runtime-token cart success, cart failure, and the served widget version in a cache-bypassed storefront session.