The five templates
Every prop each template receives, plus a starting recipe for each one.
Each template receives a props object with everything it needs already prepared — plain values, formatted strings, and ready-to-use functions. This page lists the props that matter most for each of the five templates. Values marked honor it exist for a reason — ignoring them lets shoppers add items they shouldn't be able to.
The exact prop list for the template you're editing is also shown in the app, right inside the editor.
Full layout — the whole arrangement
Root class: oxify-bundle-builder-layout
Replaces where every piece sits rather than what any one of them looks like. It's the biggest of the five and has its own guide, covering the props.slots pieces, the wrapper class that decides whether the sidebar is a sticky column or a full-width block, and three ready-to-paste recipes.
Product card — one card per product
Root class: oxify-bb-product-card
Rendered once per product in the active category. Column count (including the mobile Cards Per Row setting) is controlled by the grid, so keep your card fluid — avoid fixed widths.
| Prop | What it is |
|---|---|
props.product | The product being rendered — title, image, variants, prices, category. |
props.selectedVariant / props.onVariantChange | The chosen variant, and a function to change it. |
props.formattedPrice / props.formattedComparePrice | Prices already formatted in the store's currency — use these instead of formatting yourself. |
props.discountPercentage | Rounded percent off, or 0 when not discounted. Ready for a sale badge. |
props.isPriceLoading | True while market pricing resolves — show a placeholder rather than a possibly-wrong price. |
props.quantity | How many of this variant are already in the kit. |
props.onAddToKit / props.onRemoveFromKit | Add or remove one unit. |
props.isAddButtonDisabled | Honor it. True when the kit is full, the variant is unavailable, or pricing hasn't resolved. |
props.isOutOfStock | True when the selected variant can't be purchased. |
props.buttonText / props.outOfStockText | Merchant-set button labels. |
Recipe — sale badge only when discounted:
Category tabs — the switcher above the grid
Root class: oxify-bb-tabs
Rendered once.
| Prop | What it is |
|---|---|
props.tabs | Every tab to render, in order, including the leading "All" tab when the merchant hasn't hidden it. |
props.activeCategoryId / props.onCategoryChange | The selected tab, and a function to switch it. Pass "all" for all products. |
props.categoryImages | Category id → image URL, from the Category images setting. |
props.alignment | The merchant's tab alignment setting. |
Recipe — starting template:
Sidebar — kit summary and add-to-cart
Root class: oxify-bb-kit-sidebar
Rendered once, beside the products grid. This template also replaces the Buy Box layout (Sidebar Widget → Template 3) when active.
| Prop | What it is |
|---|---|
props.kitItems | Everything currently in the kit, one entry per unit. |
props.maxItems / props.remainingSlots / props.isComplete | How big the selected box is, how many slots are left, and whether the kit is ready to check out. |
props.onRemoveItem / props.onAddToCart | Remove a kit item by index, or check out the whole bundle. |
props.isAddToCartDisabled | Honor it. True while the kit is incomplete or a cart request is in flight. |
props.formattedOriginalPrice / props.formattedFinalPrice | Prices already formatted, ready to strike through the original. |
props.boxes / props.selectedBoxId / props.onBoxChange | Every configured box size, which one's selected, and a function to switch. |
props.showBoxSelector | True when the merchant enabled quantity-as-option. |
props.getBoxBadgeText(box) | Renders the merchant's savings badge for a box, tokens already substituted. Returns "" when the badge is off. |
props.title / props.instructionText / props.buttonText | Merchant-set sidebar text, tokens already substituted. |
props.skipCartCheckout / props.checkoutUrl | See the callout below. |
Honor skipCartCheckout
When props.skipCartCheckout is true, render the call-to-action as an anchor pointing at props.checkoutUrl rather than a plain <button> — some checkout providers only detect a real link. onAddToCart still performs the redirect for you; you only need to change the element:
Recipe — box tabs with savings badges:
Toast — the confirmation message
Root class: oxify-bb-toast
Rendered only while a message is active.
| Prop | What it is |
|---|---|
props.message | The message to show. Never empty when this template renders. |
Recipe — starting template:
What happens if the app adds new props later?
Existing templates keep working — new capabilities are added to props, never removed. New props show up in the in-app props reference and here.