2.0 Beta

Smootify 2.0 is in public beta. Your 1.x store keeps working. Move when you want.

What changed

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.

v2.0 betaAdd-on: Magic Add-ons
Open .md
On this page
  1. 1. Choose the add-ons in Shopify
  2. 2. Add the add-ons to the form
  3. 3. Pick a picker
  4. 4. Prices and quantities
  5. 5. One line in the cart
  6. 6. Keep add-on products out of lists and search
  7. Before you publish

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

  1. 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.
  2. 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.

  1. Inside the form, add a smootify-product with data-id="metafields.custom.add_ons" and data-parent-id set 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 as data-id="metafields.custom.accessories": its type must be a list of products, and its definition needs Storefront access.
  2. Inside it, put one add-on picker (next section) and whatever you want to show about the add-on: product="title", an image, a smootify-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:

addon-checkbox

A Webflow Checkbox

Adds
The add-on's current variant, while checked.
Label
Stays as you write it.
No add-on
The box unchecked.
addon-select

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".
addon-dropdown

A Webflow Dropdown

Adds
The variant chosen in the dropdown.
Template
The first Dropdown link. show-price adds 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.
addon-popover

An element with a popover

Adds
The variant chosen in the popover.
Template
The first link or button in the popover. show-price as in the dropdown.
No add-on
With allow-unselect, a "None" entry comes first. Without it, the first variant is chosen from the start.
addon-swatches

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-total 2, missing-units 1

Within the limit: 3 of 3

Class
None.
Add button
Enabled.
condition
Neither shows.
bundle-limit
current-total 3

Above the limit: 4 of 3

Class
is-above-bundle-limits
Add button
Disabled.
condition
above-bundle-limits
bundle-limit
current-total 4, above-units 1

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:

Combinations

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" on smootify-add-to-cart: without it, Smootify does not read the combinations.
box-title · box-image

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.
Otherwise

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.

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.hidden with the value 1. To set it in the admin, first add a product metafield definition with namespace seo, key hidden and 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 as data-query="-product_type:Add-on" with data-sort="BEST_SELLING", or pick the products by collection with data-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-id is not the product’s shopifyId.
  • An add-on disappears. It is inside an element with the hidden attribute: 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-dropdown or addon-popover without allow-unselect starts on the first variant.

    ↑ ↓ to moveEnter to openEsc to close