Product add-ons
Offer other products next to the main one, in its add-to-cart form, with checkboxes, selects, dropdowns, popovers or swatches, and send them to the cart as one line with the product.
Add-ons are other products the customer can add together with the one on the page: a gift wrap, an extended warranty, a case for a phone. They sit in the product’s add-to-cart form, and they go to the cart together with the product, as one line. This page covers the Shopify side, the five kinds of add-on picker, prices and quantity limits.
Note
In the Smootify dashboard, turn on Magic Add-ons and Magic Box. Both are free. Magic Add-ons adds the product metafields Add ons and Combinations and the Combinations metaobject definition to Shopify. Magic Box adds the checkout function that merges the product and its add-ons into one line.
1. Choose the add-ons in Shopify
- In Shopify, open the main product and fill its Add ons metafield with the products to offer. Any other product metafield that holds a list of products works too, such as one your store already uses for accessories.
- In Settings > Custom data, check that the Add ons and Combinations product metafields and the Combinations metaobject have Storefront access. Smootify creates them with it, but a definition that already existed in the store keeps its own setting.
An add-on is an ordinary Shopify product, with its own price, variants and stock.
2. Add the add-ons to the form
Add-ons go inside the <form> of the product’s smootify-add-to-cart. Only the fields inside the form reach the cart.
- Inside the form, add a
smootify-productwithdata-id="metafields.custom.add_ons"anddata-parent-idset to the Shopify ID of the page’s product (product.shopifyId). Smootify repeats this element once per product in the Add ons metafield. For another metafield, write its namespace and key instead, such asdata-id="metafields.custom.accessories": its type must be a list of products, and its definition needs Storefront access. - Inside it, put one add-on picker (next section) and whatever you want to show about the add-on:
product="title", an image, asmootify-price.
<smootify-add-to-cart>
<form>
<div>
<smootify-product data-id="metafields.custom.add_ons" data-parent-id={product.shopifyId}>
<addon-checkbox>
<label><input type="checkbox" name="addon"><span form-label>Add-on</span></label>
</addon-checkbox>
<div product="title">Add-on name</div>
<smootify-price><div data-prop="price">$0.00</div></smootify-price>
</smootify-product>
</div>
<div>Total: <span bundle="total">$0.00</span></div>
<input type="submit" value="Add to cart">
</form>
<div form-fail hidden>Something went wrong</div>
</smootify-add-to-cart>To offer one fixed product instead of the metafield list, give the inner smootify-product that product’s id in data-id.
What is up to you: the layout of the list (a grid, a row of cards, a popover), what each add-on shows, and which picker each one uses.
The fields of a picker take any name. Write what you like, such as addon. Smootify renames the picker’s fields itself, and they never reach the cart line as a property, not even when the customer adds to cart before the add-on has loaded.
3. Pick a picker
Each add-on needs one of these elements inside its smootify-product:
A Webflow Checkbox
- Adds
- The add-on's current variant, while checked.
- Label
- Stays as you write it.
- No add-on
- The box unchecked.
A Select field
- Adds
- The variant chosen in the select.
- Options
- Smootify writes one per variant.
- No add-on
- An option you add without a value, such as "No thanks".
A Webflow Dropdown
- Adds
- The variant chosen in the dropdown.
- Template
- The first Dropdown link.
show-priceadds the price after each name. - No add-on
- With
allow-unselect, a "None" entry comes first. Without it, the first variant is chosen from the start.
An element with a popover
- Adds
- The variant chosen in the popover.
- Template
- The first link or button in the popover.
show-priceas in the dropdown. - No add-on
- With
allow-unselect, a "None" entry comes first. Without it, the first variant is chosen from the start.
Custom elements with the tag button
- Adds
- The value or variant of the chosen button. It gets
is-active. - Template
- The first button: one per value with one option, one per variant with more.
- No add-on
- A click on the chosen button.
allow-unselect="false"prevents it and chooses the first value.
single-addon-swatch on smootify-add-to-cart keeps only one swatch add-on chosen at a time. The swatch buttons of a product with one option take the swatch parts of the variant swatches (option="title", option="image", option="bg-color").
<smootify-product data-id="1234567890">
<addon-swatches>
<button type="button"><span option="title">Value</span><smootify-price><span data-prop="price">$0.00</span></smootify-price></button>
</addon-swatches>
</smootify-product>
<smootify-product data-id="1234567890">
<addon-popover show-price="true" allow-unselect="true">
<button type="button" popovertarget="addon-variants">Choose</button>
<div id="addon-variants" popover>
<button type="button">Variant</button>
</div>
</addon-popover>
</smootify-product>A smootify-price inside a swatch button shows the price of that button’s value. A checked checkbox gives its smootify-product the class is-checked.
4. Prices and quantities
The total. With add-ons chosen, data-prop="total" of the main smootify-price includes them. bundle="total", anywhere in smootify-add-to-cart, shows the same total: the product and its chosen add-ons. An img with bundle="images" is copied once per chosen add-on, with that add-on’s picture, each copy stacked over the one before. Both stay hidden while the form has no add-on picker.
Quantity. An add-on without its own quantity field follows the quantity of the main product: one add-on for each unit. To let the customer choose it, put a quantity-input with an input inside the picker, as on the product page. The number the customer picks is per unit of the main product: 2 batteries with 2 cameras puts 4 batteries in the cart, and the total counts 4. For a quantity for the whole order instead, such as one greeting card whatever the number of pieces, give the picker the attribute quantity="total". In an addon-checkbox, the field starts at 0, and a quantity above 0 checks the box.
Limits for all the add-ons together. On the input of an add-on’s quantity-input, these attributes limit the sum of the add-on quantities, for each unit of the main product:
global-min: at least this many add-ons;global-max: at most this many;global-total: exactly this many.
Put them on one add-on’s field only. While the add-ons are outside the limits, the add button is disabled and smootify-add-to-cart gets a class. Inside the form, condition="below-bundle-limits" and condition="above-bundle-limits" show a message only in that state, and bundle-limit shows the numbers. A box of chocolates with global-total="3" needs exactly 3 add-ons:
Below the limit: 2 of 3
- Class
is-below-bundle-limits- Add button
- Disabled.
- condition
below-bundle-limits- bundle-limit
current-total2,missing-units1
Within the limit: 3 of 3
- Class
- None.
- Add button
- Enabled.
- condition
- Neither shows.
- bundle-limit
current-total3
Above the limit: 4 of 3
- Class
is-above-bundle-limits- Add button
- Disabled.
- condition
above-bundle-limits- bundle-limit
current-total4,above-units1
Add-ons and subscriptions. Add-ons are for one-time purchases. While the customer picks a subscription plan, each add-on picker takes the is-disabled class, its fields are disabled and the add-on stays out of the total and the cart. Switching back to one-time brings the choice back. On product pages that sell both, style .is-disabled in your CSS, for example with lower opacity or by hiding the block, or show a note such as “Gift wrap is for one-time orders”.
5. One line in the cart
When the customer adds the product with add-ons, they go to the cart together. With Magic Box turned on, the cart and checkout show them as one line, with the product and its add-ons inside. In the cart, a box-item inside the cart-item template lists them. The quantity of that line cannot be changed in the cart.
The line takes its title and image from the first of these that applies:
1. A combination
- Set in
- Shopify, Content › Metaobjects › Combinations: an entry with a Title, an Image and Variants, listed in the product's Combinations metafield.
- Variants
- The add-ons only, not the main product.
- Used when
- The chosen add-on variants are exactly those.
- Needs
use-magic-box="true"onsmootify-add-to-cart: without it, Smootify does not read the combinations.
2. Attributes on the form
- Set on
smootify-add-to-cart- Image
- A Shopify file (Content › Files): checkout ignores an image from anywhere else.
- Used when
- No combination matches.
3. The main product
- Title and image
- The main product's name and image.
- Used when
- Neither of the above.
For a tablet with a pen and a keyboard as add-ons, three combinations cover every choice: the pen, the keyboard, and the pen with the keyboard.
6. Keep add-on products out of lists and search
An add-on such as a gift wrap is a product of its own, so it can show up wherever the store lists products. Keep it out in two places:
- Search and the content collections. In Shopify, give the add-on the metafield
seo.hiddenwith the value1. To set it in the admin, first add a product metafield definition with namespaceseo, keyhiddenand type integer, with Storefronts access on. Shopify then leaves the product out of its search, and so do Smootify’s predictive search and search page. The change takes a few minutes. Smootify’s loaders skip it too, like the Webflow sync: from the next build it has no page, no card in the lists you render from the content collections and no line in the sitemap. The add-on still loads by its id, so it keeps working on the product page. - Collections and product lists. Keep the add-on out of your collections, including automated ones. A collection page lists only the products in it. A product list that runs a query of its own, such as best sellers, newest products or a custom query, can still show the add-on: the store’s best sellers (
data-id="best-seller") come from the whole store. Use a custom query that leaves it out, such asdata-query="-product_type:Add-on"withdata-sort="BEST_SELLING", or pick the products by collection withdata-id="specific-collection".
Before you publish
Check these first
- No add-on shows. The product’s Add ons metafield is empty, or the metafield has no Storefront access, or
data-parent-idis not the product’sshopifyId. - An add-on disappears. It is inside an element with the
hiddenattribute: pickers inside one do not mount. - Add-ons are not added. The pickers are outside the
<form>, so their fields never reach the cart. - The product and its add-ons are separate lines at checkout. Magic Box is not turned on in the Smootify dashboard.
- The combination title never shows.
use-magic-box="true"is missing, or the combination lists the main product, or its variants do not match the chosen add-ons exactly. - An add-on does nothing. A subscription plan is picked: add-ons go only with the one-time purchase, and the picker has
is-disabled. - An add-on is always added. An
addon-dropdownoraddon-popoverwithoutallow-unselectstarts on the first variant.