For developers
Optional hooks for developers of apps that sell kits or bundles of a product, such as “buy 3 and save”, from an app block on the product page. The theme needs none of this to work: without such a block, these events never fire and the page works as described in Product pages.
Before you edit code: duplicate the theme first and work on the copy (see Duplicate the theme). The hooks below are described so that your app can use them; writing or debugging code that uses them is a customization and is not covered by theme support. If you need help with custom code, we suggest hiring a Shopify Partner.
kit:change
Dispatch a CustomEvent named kit:change on document every time the shopper changes the kit in your block. The theme’s product page (the Product information section) listens to it.
document.dispatchEvent(new CustomEvent('kit:change', {
detail: {
productId: 1234567890, // the product of the page
quantity: 3, // units in the kit; 1 = back to one unit
percent: 15, // the kit's discount, in percent
unitPrice: 2125, // price per unit in the kit, in cents
compareAtUnit: 2500, // full price per unit, in cents
total: 6375, // price of the kit, in cents
compareAtTotal: 7500, // full price of the kit, in cents
saving: 1125, // total saving, in cents
formatted: { // the same amounts, formatted with the shop's money format
unit: '$21.25',
compareAtUnit: '$25.00',
total: '$63.75',
compareAtTotal: '$75.00',
saving: '$11.25'
},
activeIndex: 0, // the kit item being chosen (0 = the first); -1 with one unit
variantId: 9876543210, // the variant chosen for that item, or null
complete: false // whether every item of the kit has a variant
}
}));
What the theme does with it:
- It ignores the event when
productIdisn’t the product of the page. - When
quantityis 2 or more andformatted.unitandformatted.totalare filled in, the price block shows the price per unit in the kit, the full price per unit struck through (whencompareAtUnitis higher thanunitPrice), a badge such as “15% off in Kit 3” (whenpercentis above 0), the words “per unit in Kit 3”, and a line such as “Kit of 3 units: $63.75 · you save $11.25” (the saving only whensavingis above 0). The unit price and the Shop Pay Installments banner step out while the kit is on show. - The gallery shows the image of
variantId, when that variant has one. It moves only whenactiveIndexorvariantIdchanges. - When
quantityis 1, the price block and the gallery go back to the variant chosen in the theme’s own picker.
The theme never formats money: it writes the formatted strings as they come, and an event without them changes nothing. The words come from the theme’s translations, so merchants can change them in Edit default theme content. The price block keeps the line in a live region, so screen readers announce the kit when it changes.
kit:added
After your block has added the kit to the cart, dispatch a cancelable kit:added event on document:
const event = new CustomEvent('kit:added', {
cancelable: true,
detail: {
productId: 1234567890,
quantity: 3,
instance: 'kit-1', // your own id for this kit
items: [{ id: 9876543210, quantity: 3 }] // the variants added to the cart
}
});
document.dispatchEvent(event);
if (!event.defaultPrevented) {
window.location.href = `${window.Shopify?.routes?.root ?? '/'}cart`;
}
When the merchant uses the cart drawer (Theme settings › Cart › Cart type set to Drawer), the theme cancels the event, opens the drawer and redraws it, so the shopper stays on the page. When the event is not cancelled, the cart drawer isn’t in use, and your block can send the shopper to the cart page as in the example.
html[data-kit-active]
While the shopper builds a kit in your block, set the data-kit-active attribute on the <html> element, and remove it when they go back to buying one unit:
document.documentElement.toggleAttribute('data-kit-active', quantity > 1);
With the attribute present, the theme hides the Variant picker and Buy buttons blocks of the product page, since your block brings its own, so the page never shows two add buttons. On phones, the page also stops keeping room for the theme’s buy bar at the bottom of the screen.