2.0 Beta

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

What changed

Magic Box

A box the customer fills with products you choose, under rules you set, that reaches the cart and checkout as one line with its own title, image and discount.

v2.0 betaAdd-on: Magic Box
Open .md1.x page ↗
On this page
  1. How it fits together
  2. 1. Give the box a title, an image and a discount
  3. 2. Build the box
  4. 3. Set the size of the box
  5. 4. One product per category
  6. 5. Show progress and the price
  7. 6. In the cart and at checkout
  8. Before you publish
  9. Coming from 1.x

Magic Box lets the customer build a box: a case of 6 wines, a sampler of 3 coffees, a PC with one part from each category. The customer picks products from the lists you design, and the box goes to the cart as one line, with its own title and image. At checkout it stays one line, and it can carry a discount. This page covers the Shopify side, the box, its rules, categories and the box panel.

Note

Turn on Magic Box in the Smootify dashboard of the site. It is included in every plan, the free one too, but it always needs to be turned on, also on your .webflow.io address. Turning it on adds the Magic Box metaobject definition to Shopify and the checkout function that merges the box into one line.

How it fits together

Everything goes inside one Custom element, smootify-magic-box.

What Smootify needs:

  • a smootify-magic-box element;
  • inside it, the products the customer can pick, each with its own add-to-cart form. Inside the box, these forms add to the box instead of the cart;
  • inside it, a smootify-magic-box-cart: the box panel. It holds a box-item template, repeated once per product in the box, and a Form Block that adds the whole box to the cart. Without it, the box is removed.

What is up to you:

  • how the products are listed: a Collection list, several lists, a Slider or Tabs;
  • where the box panel sits (a sidebar, a sticky bar, under the products) and what it shows;
  • the layout, classes and styles of every part.

A fixed box of 6 looks like this in the Navigator:

Example structure of the Navigator
smootify-magic-boxCustom Elementdata-min=6data-max=6
Collection List WrapperSource ProductsFilter Collections contains Wines
Collection List
Collection Item
smootify-productCustom Elementdata-id=Shopify ID
Text BlockNameproduct=title
smootify-add-to-cartCustom Element
Form Block
Form
Form Button“Add to box”
Success Message
Text Block“Added”
Error Message
Text Block“Something went wrong”
smootify-magic-box-cartCustom Element
items-listCustom Element
box-itemCustom Element
Text Block“Product”box-item=title
Text Block“1”box-item=quantity
buttonCustom Elementdata-action=remove
Text“Remove”
empty-stateCustom Element
Text“Your box is empty”
Form Block
Form
Form Button“Add the box to cart”
Success Message
Text Block“Added”
Error Message
Text Block“Something went wrong”

1. Give the box a title, an image and a discount

In the cart and at checkout, the box line shows a title and an image of its own. There are two ways to set them.

A Magic Box entry in Shopify. In Shopify, go to Content > Metaobjects > Magic Box and create an entry with a Title, an Image and, if you want one, a Discount Percentage. On smootify-magic-box, set data-handle to the entry’s handle. The merchant can then change the title, the image or the discount in Shopify without touching the site.

A static box. Set data-title and data-image on smootify-magic-box. The image must be a Shopify file: upload it in Shopify under Content > Files and copy its URL. Checkout ignores an image from anywhere else.

Warning

The discount can only come from a Magic Box entry. A static box has no discount.

The discount applies to every box the customer can add to the cart under its limits, not only to a full one. For a discount only on a full box, give the box the same data-min and data-max, such as data-min="12" data-max="12".

The discount is a percentage off the whole box, applied at checkout.

2. Build the box

  1. Add a Custom element with the tag smootify-magic-box around the products and the box panel.
  2. Inside it, list the products. Any list works: a Collection list of product cards, or a list loaded from Shopify without the CMS (product lists). Each card needs a smootify-add-to-cart with a Form Block inside. Its button adds the product to the box. Variant pickers and a quantity field work as on the product page.
  3. Inside smootify-magic-box, add a Custom element with the tag smootify-magic-box-cart. Put inside it:
    • a Custom element with the tag items-list, holding one Custom element with the tag box-item. The box-item is the template: Smootify repeats it for each product in the box. items-list shows only while the box has products;
    • optionally, a Custom element with the tag empty-state, shown only while the box is empty;
    • a Form Block with a submit button. It adds the whole box to the cart.

Inside box-item:

  • box-item="title", box-item="image", box-item="price", box-item="total" (price × quantity), box-item="quantity" and box-item="category" show the product in the box;
  • the product and variant values also work, such as variant="title" for the variant name. See box item values;
  • a Custom element with the tag button and data-action="remove" takes the product out of the box.

After a product goes into the box, the quantity field of its form goes back to 1.

3. Set the size of the box

These attributes go on smootify-magic-box:

AttributeWhat it doesDefault
data-minthe fewest products the box can hold1
data-maxthe most products the box can hold100 (also the highest value)
data-stepthe box size must be a multiple of this1
data-uniquethe same product can go in only onceoff

The box can be bought when the number of products is between data-min and data-max and a multiple of data-step. The add button stays disabled until then. Some sizes and the boxes they allow:

data-min="6" data-max="6"

A fixed size

Can be bought
With exactly 6 products.
data-min="6" data-max="12" data-step="6"

Sizes you choose

Can be bought
With 6 or 12 products, nothing in between.
data-max="10"

A free mix with a limit

Can be bought
From 1 to 10 products: data-min is 1 unless you set it.
data-min="10" data-max="25" data-step="15"

Sizes that do not share the step

Can be bought
With 15 products only: 10 and 25 are not multiples of 15.
Instead
A box of 10 or 20 needs data-step="10".

Warning

Every size must be a multiple of the same step. A box of 1, 3 or 6 cannot be written with one step.

data-unique and the category rules below are on whenever they have a value, even false. Write true, and remove the attribute to turn a rule off.

When a product does not fit, the product’s form shows an error in its Error message. You can change the text of each error:

  • data-full-error: the box is full. Default “Box is full”;
  • data-too-many-error: the quantity is more than what fits. {quantity} in the text becomes the number that still fits;
  • data-only-one: the product is already in the box and data-unique is on. Default “You can add only 1 item inside the box”;
  • data-only-one-per-category: the category already has a product. {category} becomes the category name. Default “You can add only 1 item of {category} inside the box”.

4. One product per category

For a box that needs one piece from each group (a base, a sauce and a topping; a PC with a motherboard, a GPU and RAM), split the products into categories.

  1. Wrap each group of products in a Custom element with the tag smootify-box-category.
  2. Give it the custom attribute data-name with the category name, such as Sauce.
Example structure of the Navigator
smootify-box-categoryCustom Elementdata-name=Sauce
Collection List WrapperSource ProductsFilter Collections contains Sauces
Collection List
Collection Item
smootify-productCustom Elementdata-id=Shopify ID
Text BlockNameproduct=title
smootify-add-to-cartCustom Element
Form Block
Form
Form Button“Add”
Success Message
Text Block“Added”
Error Message
Text Block“Something went wrong”

Then choose the rules on smootify-magic-box. For a pizza with a Base, a Sauce and a Topping:

data-unique-per-category="true"

One product per category

A second pick
In the same category, it shows an error in the Error message of the product's form.
data-auto-remove-category="true"

A new pick replaces the old one

Works
Only with one product per category on.
A second pick
Takes the place of the first in its category, with no error. For a configurator.
data-all-categories="true"

Every category filled

Can be bought
Only when every category has a product.
Until then
The add button stays disabled.

Steps without interactions. Put each category in a slide of a Webflow Slider, or in a pane of a Webflow Tabs element. When the customer adds a product, the Slider or Tabs moves on: to the next empty category with data-all-categories, otherwise to the next slide or tab. When the customer removes a product, it goes back to that product’s category.

Completed categories. A category gets the class is-complete while the box holds at least one of its products, and so do the slide and the tab link that show it when every category in them has one. To show a check mark inside a tab link, put it in an element with box-condition="category-complete"; box-condition="category-incomplete" is the opposite.

In the box panel, data-prop="missingCategories" lists the categories still empty, separated by commas. separator changes the separator, and separator="repeat" makes one copy of the element per missing category.

5. Show progress and the price

Inside smootify-magic-box-cart, outside the box-item, these elements follow the box:

Example structure of the Navigator
Div Block
Text Span“0”data-prop=currentQuantity
Text“/”
Text Span“6”data-prop=maxQuantity
Div Block
Div Blockdata-prop=leftQuantityWidth
Div Blockbox-condition=cannot-purchase
Text“Missing:”
Text Span“Base, Sauce”data-prop=missingCategories
smootify-priceCustom Element
Text Block“$0.00”data-prop=price
Text Block“$0.00”data-prop=compareAtPrice
Div Blockbox-condition=can-purchase
Text“You save”
Text Span“$0.00”data-prop=discount-amount
  • data-prop="currentQuantity", "minQuantity", "maxQuantity", "leftQuantity" (how many more fit): numbers;
  • data-prop="leftQuantityWidth" on a Div block: its width follows how full the box is, for a progress bar. data-prop="leftQuantityPercentage" shows the same as text;
  • data-prop="discount-percentage" and data-prop="discount-amount": the discount of the box, as a percentage and as money;
  • a smootify-price shows the box total after the discount in data-prop="price", and the total before the discount in data-prop="compareAtPrice" when there is one;
  • box-condition="can-purchase" and box-condition="cannot-purchase" show an element only while the box can, or cannot yet, be bought.

smootify-magic-box-cart also gets classes you can style as combo classes. For a box of 6 wines at $20.00 each, the panel goes through these states:

is-empty · is-disabled

Empty

Shows
empty-state instead of items-list, and box-condition="cannot-purchase".
Add button
Disabled.
is-disabled

Filling: 4 of 6

Shows
items-list and box-condition="cannot-purchase".
Add button
Disabled.
is-purchasable

Ready: 6 of 6

Shows
box-condition="can-purchase".
Add button
Enabled.
is-purchasable · is-saving

Ready, with a 10% discount

Discount
From the Magic Box entry. is-saving while it applies.
Price
data-prop="price" after the discount, data-prop="compareAtPrice" before it.

The full lists are in Magic Box values and Magic Box conditions.

The add button. A Form Button works, or a Custom element with the tag button and type="submit". It is disabled until the box can be bought. A second Custom element with the tag button, type="submit" and name="buy-now" adds the box and goes straight to checkout. data-buy-now="true" on smootify-magic-box-cart sends every submit to checkout.

Extra fields. A field in the box’s form, such as a gift message, is saved with the box, under its field name, and shows with the box in the cart. A name that starts with _ is saved but not shown.

6. In the cart and at checkout

The box is one line in the cart, with the box title and image. In the cart, a box-item inside the cart-item template repeats once per product in the box, with the cart line values such as box-item="title" and box-item="quantity". The customer cannot change the quantity of a box: its quantity field is removed. With a box-item in the template, cart-item="options" lists only the box’s own fields, such as a gift message. Without one, it lists the products as text (“1 x Wool Socks”), as 1.x did.

At checkout Shopify shows the box as one line, with its title, image and discount.

Subscriptions. A box cannot be sold as a subscription: Shopify does not merge cart lines that have a selling plan. See subscriptions for what you can build instead.

Developers can add a box to the cart from code with addBoxToCart. They can also change the box title and image as the box fills, for example “Box of 4 wines”: see the Magic Box example.

Before you publish

On your .webflow.io address, the Smootify debugger lists the Magic Box elements and tells you when they are not running. See the debugger.

Check these first

  • Products go straight to the cart, one at a time. Magic Box is not turned on in the Smootify dashboard. It needs to be on, also on .webflow.io.
  • The whole box disappears. smootify-magic-box-cart is missing, or data-handle does not match the handle of a Magic Box entry in Shopify.
  • The add button never turns on. The number of products is not between data-min and data-max, or not a multiple of data-step, or a category is empty with data-all-categories.
  • There is no discount. The box is static (data-title, data-image). Only a Magic Box entry carries a discount.
  • The box image is missing at checkout. The data-image URL is not a Shopify file. Upload it under Content > Files.
  • A rule is on though you wrote false. These rules turn on with any value. Remove the attribute instead.

Coming from 1.x

  • The default texts of data-only-one and data-only-one-per-category say “inside the box”, where 1.x said “inside the cart”.

    ↑ ↓ to moveEnter to openEsc to close