Skip to main content

Smootify

Purpose: Bridge between Webflow design flexibility and Shopify ecommerce power, enabling headless Shopify stores within Webflow projects.

Last verified: December 2025


Account Details​

  • Notes: webflow ecommerce plugin to provide headless shopify
  • Category: WEBSITE
  • Account type: INTERNAL
  • Created: December 2025
  • Access URL: https://dashboard.smootify.io
  • Account owner: Ben Power

Overview​

Smootify bridges the gap between the design flexibility of Webflow and the robust e-commerce power of Shopify, empowering you to build headless Shopify stores directly within your Webflow projects. This enables you to leverage Webflow's visual design capabilities while using Shopify as the ecommerce backend for products, orders, inventory, and customer management.


Initial Setup​

Prerequisites​

Before starting, ensure you have:

  • A Shopify store with products set up
  • A Webflow project ready for ecommerce integration
  • Access to both Shopify admin and Webflow designer

Installation Steps​

  1. Install Smootify App

    • Install the Smootify app from either the Shopify App Store or Webflow App Store
    • Connect your Shopify store and Webflow project
  2. Install Shopify Headless App (Critical)

    • Install the Shopify Headless App on the same Shopify store
    • This enables essential features:
      • Order confirmation emails
      • Customer accounts
      • Other headless commerce functionalities

Shopify Headless App Configuration​

The Shopify Headless App is essential for proper functionality. Follow these steps:

Development Token vs Live Token​

Important: The Smootify Shopify App automatically generates a development storefront token upon installation. This allows you to quickly preview and begin building without further configuration.

However, before launching your store to the public, you MUST generate a new storefront token using the official Shopify Headless sales channel.

Why Transition to Live Mode?​

  1. Order Confirmation Notifications: The development token does not support order confirmation notifications. Generating a token through the Shopify Headless sales channel is essential for enabling these crucial customer communications.

  2. Sales Channel Attribution: The development token doesn't allow you to create a sales channel name. For multi-channel stores (Facebook, Instagram, Shop, etc.), it's fundamental to be able to discern sales from the Webflow site. This can only be done by creating a token with the Headless App. The name you use to create the token will be the sales channel name you see in the orders dashboard.

Step 1: Install Headless App​

  1. Install the Shopify Headless App on the same Shopify store
  2. This enables essential features:
    • Order confirmation emails
    • Customer accounts
    • Other headless commerce functionalities

Step 2: Create Storefront​

  1. In the Shopify Headless App, click Create Storefront
  2. This sets up the Storefront API connection

Step 3: Manage Storefront API​

  1. Click Manage Storefront API
  2. Click Edit to configure permissions
  3. Enable all Storefront API permissions (critical for full functionality)
  4. Click Save changes

Step 4: Get Public Token​

  1. After saving, copy the public token (Storefront API access token)
  2. This token will be used in Smootify dashboard configuration

Step 5: Configure in Smootify Dashboard​

  1. Go to Site settings in your Smootify dashboard
  2. Click Edit Info
  3. Replace the existing development token with the new live public token from Shopify
  4. Click Save Info

Important: Without the Shopify Headless App properly configured with a live token, order confirmation emails, customer accounts, and sales channel attribution will not work.


Webflow Project Connection​

Connect Your Webflow Project​

  1. In Smootify dashboard, connect your Webflow project
  2. Ensure you have the correct Webflow site ID
  3. Verify the connection is active

Create CMS Collections​

After connecting your Webflow project, you'll need to create CMS collections that Smootify will populate with Shopify data:

Required Collections:

  • Products collection - For product data
  • Collections collection - For product collections/categories
  • Vendors collection - For vendor/brand information (if applicable)

Optional Collections:

  • Account pages folder - For customer account pages

These collections will be automatically synced with your Shopify store data.


Custom Code Configuration​

Smootify allows you to customize behaviour using JavaScript configuration scripts. You can either write custom code or use the built-in customizer.

Using the Customizer​

The Smootify dashboard includes a customizer that generates the proper script without requiring manual coding:

Configuration Options:

OptionDescription
Slug of Products CMS collectionThe Webflow CMS collection slug for products
Slug of Collections CMS collectionThe Webflow CMS collection slug for collections
Slug of Vendors CMS collectionThe Webflow CMS collection slug for vendors
Slug of Account pages folderThe Webflow folder slug for account pages
Public Key for Customer AccountsPublic key for customer account functionality
Order Page UrlURL for order confirmation pages
Subscription Page UrlURL for subscription management pages
Restricted Pages RedirectRedirect URL for restricted/unauthorized pages
Cache DurationHow long to cache data (performance optimization)
Show only images of currently selected variantFilter product images by selected variant
Select market based on browser languageAuto-select market based on user's browser language
Enable Auto Analytics TrackingAutomatically track ecommerce events
Format prices based on browser settingsLocalize price formatting
Preload products on idle timePerformance optimization - preload products when browser is idle

After configuring, click Copy Script to get the generated configuration code.

Custom JavaScript Configuration​

If you need more control, you can write custom JavaScript configuration. The customizer generates the proper script structure that you can then modify.


Smootify APIs​

Smootify exposes JavaScript APIs for advanced customization and integration. These APIs allow you to interact with Shopify's Storefront API, manage cart operations, handle customer data, and customise market settings.

Wait for Smootify to Load​

The Smootify instance is only available after APIs are loaded. Always wrap your code in the API loaded callback:

document.addEventListener("smootify:loaded", () => {
console.log("Smootify APIs are available");
// Your code here
});

Alternative: Script Loading​

If you're hosting scripts elsewhere (not inline), you can use the smootify-load script type. The script will be loaded after APIs are available:

<script
src="https://yourcdnurl.tld/yourscript.js"
type="smootify-load"
data-type="module"
></script>

Note: You can also upload JS files to Shopify > Content > Files and use that as a CDN if needed.

Query API​

Access the Shopify Storefront GraphQL API without managing fetch calls, tokens, or authentication:

Syntax​

Smootify.query(query);
Smootify.query(query, variables);

Parameters​

ParameterTypeDefaultDescription
querystring-GraphQL query string
variablesRecord<string,any>Optional query variables

Example: Get Shop ID​

document.addEventListener("smootify:loaded", async () => {
const result = await Smootify.query(`{
shop {
id
}
}`);

const shopID = result.shop.id;
console.log("Shop ID:", shopID);
});

The Query API handles all authentication, token management, and API calls automatically.

Query Customer API​

Query customer fields for the currently logged in customer. This automatically fetches from either the legacy or new Customer Accounts API based on whether you're using passwordless login.

Important: This is limited to querying the Customer object only, not the full Customer Accounts API.

Error Handling: If the customer is not logged in, this will throw an error. Always wrap calls in try/catch blocks.

Syntax​

Smootify.queryCustomer(fields);

Parameters​

ParameterTypeDefaultDescription
fieldsstring-GraphQL fields to query (Customer object schema)

Example: Load Metafield After Customer Status Loaded​

document.addEventListener('smootify:user_auth_change', async (event) => {
const shopifyCustomer = event.detail;
if (shopifyCustomer) {
try {
const {customer} = await Smootify.queryCustomer(`
id
customField: metafield(namespace:"custom", key:"my_key") {
value
}
`);
console.log(customer.id, customer.customField);
} catch (e) {
console.log('Customer not logged in or error with the query', e);
}
} else {
// Customer logged out - redirect if needed
}
});

Example: Query Metafield on Button Click​

document.getElementById('my-button').addEventListener('click', async () => {
try {
const {customer} = await Smootify.queryCustomer(`
id
customField: metafield(namespace:"custom", key:"my_key") {
value
}
`);
console.log(customer.id, customer.customField);
} catch (e) {
console.log('Customer not logged in or error with the query', e);
}
});

Set Customer Metafields API​

Set customer metafields for the currently logged in customer. Ensure metafields are set as readable/writable from Customer Accounts API.

Important:

  • If the customer is not logged in, this will throw an error. Handle errors appropriately.
  • This method is not available if you're using legacy customer accounts.

Syntax​

Smootify.setCustomerMetafields(...metafields);

Parameters​

ParameterTypeDefaultDescription
metafieldsObject-One or more metafield objects with key and value properties

Example: Save Metafield After Customer Status Loaded​

document.addEventListener('smootify:user_auth_change', async (event) => {
const shopifyCustomer = event.detail;
if (shopifyCustomer) {
try {
await Smootify.setCustomerMetafields(
{
key: "popup_seen",
value: "true"
},
{
key: "last_viewed_page",
value: window.location.pathname
}
);
} catch (e) {
console.log('Error setting customer metafields', e);
}
}
});

Apply Coupon Code API​

Apply a coupon code to the cart without user interaction. Useful for adding specific coupon codes based on JavaScript interactions.

Syntax​

Smootify.applyCouponCode(code);

Parameters​

ParameterTypeDefaultDescription
codestring-Coupon code to apply

Example: Add Coupon Code on Button Click​

document.getElementById("welcome-button").addEventListener("click", () => {
Smootify.applyCouponCode("welcome20");
});

Change Market By Country ISO Code API​

Change the market by ISO country code. Useful for IP localisation or manual market selection.

Syntax​

Smootify.changeCountryByIsoCode(isoCode);

Parameters​

ParameterTypeDefaultDescription
isoCodestring-ISO country code (e.g., "IT", "US", "GB")

Example: Change Market to Italy on Button Click​

document.getElementById("italy-button").addEventListener("click", () => {
Smootify.changeCountryByIsoCode("IT");
});

Change Market Language API​

Change the market language. Useful for IP localisation or manual language selection.

Syntax​

Smootify.changeMarketLanguage(isoCode);

Parameters​

ParameterTypeDefaultDescription
isoCodestring-ISO language code (e.g., "IT", "EN", "FR")

Example: Change Language to Italian on Button Click​

document.getElementById("italy-button").addEventListener("click", () => {
Smootify.changeMarketLanguage("IT");
});

Add to Cart API​

Add lines to the cart and automatically refresh the cart render. Optionally redirect directly to checkout.

Syntax​

Smootify.addToCart(lines);
Smootify.addToCart(lines, goToCheckout);

Parameters​

ParameterTypeDefaultDescription
linesCartLineInput[]-Array of cart line items to add
goToCheckoutbooleanfalseWhether to redirect to checkout after adding

CartLineInput Structure​

{
attributes?: Array<{
key: string;
value: string;
}>;
quantity: number;
merchandiseId: string; // Format: "gid://shopify/ProductVariant/123"
}

Example: Add Item to Cart on Button Click​

document.getElementById("product-card-button").addEventListener("click", () => {
const productsToAdd = [
{
attributes: [
{
key: "Attribute Key",
value: "Attribute value",
},
],
quantity: 1,
merchandiseId: "gid://shopify/ProductVariant/1",
},
];

Smootify.addToCart(productsToAdd);
});

Example: Add Product Based on Cart Contents​

document.addEventListener("smootify:cart_updated", (event) => {
const cart = event.detail;

const userAddedMyProduct = !!cart.nodes.find(
(node) => node.merchandise.product.title == "My Product"
);

const userAddedMyOtherProduct = !!cart.nodes.find(
(node) => node.merchandise.product.title == "My Other Product"
);

if (userAddedMyProduct && !userAddedMyOtherProduct) {
const productsToAdd = [
{
attributes: [
{
key: "Attribute Key",
value: "Attribute value",
},
],
quantity: 1,
merchandiseId: "gid://shopify/ProductVariant/1",
},
];

Smootify.addToCart(productsToAdd);
}
});

Get Cart ID API​

Get the current cart ID. Useful if you want to directly mutate the cart state using your own GraphQL queries.

Syntax​

Smootify.getCartID();

Example: Set a Cart Metafield​

document.addEventListener("smootify:loaded", async () => {
const cartId = await Smootify.getCartID();

await Smootify.query(
`mutation cartMetafieldsSet($metafields: [CartMetafieldsSetInput!]!) {
cartMetafieldsSet(metafields: $metafields) {
metafields {
id
value
}
userErrors {
field
message
}
}
}`,
{
metafields: [
{
key: "<your-key>",
ownerId: cartId,
type: "<your-type>",
value: "<your-value>",
},
],
}
);
});

Reload Cart API​

Re-render the cart. Useful if you've modified the cart state using your own GraphQL queries.

Syntax​

Smootify.reloadCart();

Clear Cart API​

Remove all items from the cart.

Syntax​

Smootify.clearCart();

Format Money API​

Format a string (cents) or number as a money string based on the Shopify format.

Syntax​

Smootify.formatMoney(cents);

Parameters​

ParameterTypeDefaultDescription
centsstring | number-Price in cents (as string or number)

Example: Set Text Element as Formatted Price​

document.querySelector('.my-text').textContent = Smootify.formatMoney('100');

Add Box to Cart API​

Add a group of products as a box. This function requires the Magic Box Add-on to be enabled.

Syntax​

Smootify.addBoxToCart(lines);
Smootify.addBoxToCart(lines, boxOptions);
Smootify.addBoxToCart(lines, boxOptions, goToCheckout);

Parameters​

ParameterTypeDefaultDescription
linesCartLineInput[]-Array of cart line items to add as a box
boxOptionsBoxOptions-Optional box configuration (title, image)
goToCheckoutbooleanfalseWhether to redirect to checkout after adding

BoxOptions Structure​

{
title?: string; // Custom box title
image?: string; // Image URL (must be hosted on Shopify CDN)
}

Example: Add Box to Cart​

const productsToAdd = [
{
attributes: [
{
key: "Attribute Key",
value: "Attribute value",
},
],
quantity: 1,
merchandiseId: "gid://shopify/ProductVariant/123123123",
},
{
attributes: [
{
key: "Attribute Key",
value: "Attribute value",
},
],
quantity: 1,
merchandiseId: "gid://shopify/ProductVariant/12312312312",
},
];

const boxOptions = {
title: "My Custom Box",
image: "https://cdn.shopify.com/s/files/1/0563/0689/2909/files/image.webp", // Must be hosted on Shopify CDN
};

Smootify.addBoxToCart(productsToAdd, boxOptions);

JS Events​

Smootify dispatches custom events that you can listen to for any action made on Smootify elements. These events allow you to react to user interactions, cart changes, product loads, and more.

Global Events​

Global events are dispatched on the document element and can be listened to from anywhere in your code.

API Loaded Event​

Dispatched after all Smootify modules have been loaded. Use this to ensure APIs are available before using them.

Event Name: smootify:loaded

Example:

document.addEventListener('smootify:loaded', () => {
console.log("Smootify APIs are available");
// Your code here
});

User Auth Change Event​

Dispatched on login status change and on page load to notify if a user is effectively logged in or not.

Event Name: smootify:user_auth_change

Event Detail: Customer object (or null if logged out)

Example:

document.addEventListener('smootify:user_auth_change', (event) => {
const customer = event.detail;
if (customer) {
// User is logged in - do something with the customer object
console.log('Customer logged in:', customer);
} else {
// User is logged out - redirect if needed
console.log('Customer logged out');
}
});

Cart Updated Event​

Dispatched on any cart changes, including on the cart's first load. Useful for updating UI elements like free shipping bars, cart totals, or analytics tracking.

Event Name: smootify:cart_updated

Event Detail: Cart object

Example:

document.addEventListener('smootify:cart_updated', (event) => {
const cart = event.detail;
// Send cart analytics, open a popup, modify the free shipping bar, etc.
console.log('Cart updated:', cart);
});

Added to Cart Event​

Dispatched when any product is added to the cart.

Event Name: smootify:added_to_cart

Event Detail: Object containing lines, cart, and goToCheckout

Example:

document.addEventListener('smootify:added_to_cart', (event) => {
const {lines, cart, goToCheckout} = event.detail;
// Do something with the payload
console.log('Items added:', lines);
console.log('Updated cart:', cart);
console.log('Going to checkout:', goToCheckout);
});

Removed from Cart Event​

Dispatched when any product is removed from the cart.

Event Name: smootify:removed_from_cart

Event Detail: Array of line IDs that were removed

Example:

document.addEventListener('smootify:removed_from_cart', (event) => {
const lineIds = event.detail;
// lineIds is an array of elements removed from the cart
console.log('Items removed:', lineIds);
});

Product Loaded Event​

Dispatched for each product loaded from the API.

Event Name: smootify:product_loaded

Event Detail: Object containing id and product

Example:

document.addEventListener('smootify:product_loaded', (event) => {
const {id, product} = event.detail;
// Do something with the product
console.log('Product loaded:', id, product);
});

Images Module Loaded Event​

Dispatched every time after the Images JS module gets loaded. Note that module loaded doesn't ensure all images have been loaded.

Event Name: smootify:productImagesModuleLoaded

Example:

document.addEventListener('smootify:productImagesModuleLoaded', () => {
// Images module is loaded
console.log('Product images module loaded');
});

Addon State Changed Event​

Dispatched if you have an add to cart with Magic Addons every time an add-on gets added or removed.

Event Name: addon:state_change

Event Detail: Object containing wrapper, product, variant, and included

Example:

document.addEventListener('addon:state_change', (event) => {
const {wrapper, product, variant, included} = event.detail;
// Do something (e.g., if the addon is included, show up a property input)
if (included) {
console.log('Addon included for variant:', variant);
} else {
console.log('Addon removed for variant:', variant);
}
});

Product Custom Element Events​

These events are dispatched only on the Smootify Product Custom Element (<smootify-product>).

Variant Change Event​

Dispatched each time a new variant has been selected.

Event Name: changeVariant

Event Detail: Variant object

Example:

const productWrapper = document.querySelector('smootify-product'); // First product wrapper element
productWrapper.addEventListener('changeVariant', (event) => {
const variant = event.detail;
// Do something with the variant
console.log('Variant changed:', variant);
});

Plan Change Event​

Dispatched each time the variant plan (subscription) changes.

Event Name: changePlan

Event Detail: Object containing plan and variant. Note: plan will be null if the subscription option has been deselected.

Example:

const productWrapper = document.querySelector('smootify-product'); // First product wrapper element
productWrapper.addEventListener('changePlan', (event) => {
const {plan, variant} = event.detail;
// Do something with the variant and the plan
if (plan) {
console.log('Subscription plan selected:', plan);
} else {
console.log('Subscription plan deselected');
}
console.log('Current variant:', variant);
});

Product Variant Custom Element Events​

These events are dispatched by the Variant Custom Element.

Variants Rendered Event​

Dispatched each time the variants get rendered.

Event Name: variantsRendered

Example:

document.body.addEventListener('variantsRendered', (event) => {
// Do something after variants have been rendered
console.log('Variants rendered');
});

CSS Snippets​

Useful CSS snippets to create features that in Webflow are still not very easy to do and require pseudo elements or advanced CSS selectors.

Variant Buttons Tooltips​

When using Variant Buttons swatches, it's sometimes useful to show the buttons without any title (only image or colour for example). By adding the snippet below, you'll get a pseudo element that appears on hover and dynamically shows the title of the option.

Snippet:

<style>
variant-swatches button {
position: relative;
}

variant-swatches button:hover::before {
content: attr(data-value);
position: absolute;
top: -70%;
left: 50%;
z-index: 9999;
padding: 0.2rem 0.5rem;
transform: translateX(-50%);
height: auto;
border-radius: 0.3rem;
background-color: black;
color: white;
font-size: 0.8rem;
}
</style>

Feel free to modify the style according to your own design needs.

Disable Cart Item Skeleton​

If you want to disable the cart item skeleton loading animation, add the following snippet:

<style>
cart-item.loading>:before,
cart-item.loading bundle-item>:before,
cart-item.loading img {
animation: none !important;
}
</style>

Useful Selectors​

Below is a list of useful CSS selectors you might need in Webflow with custom code.

Custom Radio Checked​

Webflow allows you to apply the checked state only to the radio input. With the following selector, you can select the Radio Element instead:

.w-radio:has(.w--redirected-checked) {
/* Add your style */
}

Custom Checkbox Checked​

Webflow allows you to apply the checked state only to the checkbox input. With the following selector, you can select the Checkbox Element instead:

.w-checkbox:has(.w--redirected-checked) {
/* Add your style */
}

Webflow allows you to apply the open state on the menu only. With the following selector, you can select the body when a menu is open. Further refine the selector if you have multiple menus:

body:has(.w-nav-menu[aria-expanded="true"]) {
/* Add your style */
}

Custom Elements​

Smootify provides custom elements that act as the bridge between Shopify and Webflow. These elements enable:

  • Product display and variants
  • Collection filtering
  • Cart functionality
  • Checkout integration
  • Customer account features

Custom elements are added to your Webflow project and automatically connect to your Shopify store data.


Metaobjects​

Metaobjects allow you to load structured data directly from Shopify into your Webflow site. This is useful when you need to let customers modify content directly from Shopify without accessing your Webflow project, or when you want to use Smootify's Add-on Metaobject Creator for complex interactions.

Key Concepts​

Metaobject Template:

  • You design a single 'Metaobject Template' in Webflow
  • Smootify, leveraging the Shopify Storefront API, automatically replicates that template for each metaobject you have in Shopify
  • Dynamic data from the metaobject fields is then populated into each Metaobject Template

Dynamic Data Binding:

  • Custom attributes and Custom Elements within the 'Metaobject Template' dictate where dynamic Shopify data will be injected into the static elements by Smootify

Shopify Configuration​

Before using metaobjects in Webflow, you need to configure them in Shopify:

  1. Go to Shopify panel → Settings → Custom Data → Metaobjects
  2. Create the metaobject definition in whatever way you like
  3. Critical: Be sure to enable these options:
    • Active-draft status
    • Storefronts API access

Metaobject Listing​

How to design your listings in Webflow to display multiple metaobjects fetched from your Shopify store.

When to Use Metaobject Listing​

Use metaobject listings when you need to:

  • Display multiple metaobjects in a grid or list
  • Let customers modify content from Shopify without accessing Webflow
  • Use Smootify's Add-on Metaobject Creator for complex interactions
  • Show more than 10 metaobject references (Product Metafields are limited to 10)

How to Create a Metaobject Listing​

Step 1: Copy the Component​

  1. Copy the Metaobject Listing component from Smootify
  2. This component contains a list of metaobjects fetched from Shopify

Step 2: Customize the Attributes​

On the Custom Element smootify-metaobjects, modify the following Custom Attributes:

Type:

NameValue
data-typemetaobject_type_to_load

For example, if you created a Metaobject definition with type "testimonials", use:

NameValue
data-typetestimonials

Product Metafield (Optional):

Starting from Smootify v1.0.5, you can select metaobjects by a product metafield. This is useful when you need to show more references or use pagination.

To use this feature, set the data-type attribute to:

NameValue
data-typemetafield.namespace.key

Where you replace namespace.key with the actual namespace and key of the metafield. Note: The metafield type must be a list of Metaobjects.

Additionally, add the attribute:

NameValue
data-product-idproduct id

If you're in the Product Template page, you can bind the value to the CMS:

NameValue
data-product-idShopify ID

Limit (Optional):

Modify the number of metaobjects loaded by setting:

NameValue
data-limitnumber

By default it's set to 10. Avoid adding more than 100 as limit.

Step 3: Style the Grid Element​

Inside the component, you'll find a Grid Element that will contain all loaded metaobjects. Style it according to your needs.

Step 4: Style the Pagination Elements​

Inside the component, you'll find 3 pagination buttons with the following attributes:

  • Next button: data-action="next"
  • Previous button: data-action="prev"
  • Load more button: data-action="load-more"

Style them according to your needs. Important: Do not keep all 3 buttons visible at the same time. Either use previous/next OR use the load more button.

Step 5: Design the Metaobject Template Item​

In the component, you'll find a Custom Element with tag smootify-metaobject. Add inside it all Webflow elements you require to style your Metaobject Template Item.

Step 6: Add the Metaobject Attributes​

On any Webflow static element you added inside the smootify-metaobject custom element, you can add the attribute:

NameValue
metaobjectmetaobject_field_key

This binds that static element to the corresponding field defined for the metaobject.

Supported Fields​

Shopify TypeWebflow ElementsInfo
Single Line TextAny text elementWill output the text of the field
Multi Line TextAny text elementWill output the text of the field
Integer NumberAny text elementWill output the number of the field
Double NumberAny text elementWill output the number of the field. The number of digits can be customized with data-digits attribute (e.g., data-digits="2")
URLAny link elementWill output the selected link
ColorAny elementWill output on the element the CSS variable --metafield-color, unless you use property="--your-css-variable"
File / Generic FileAny link elementIf you select generic file, you can output the link
File / Image FileAny link, image, and div elementIf used on a link element, the link to the image will be rendered. On all other elements, you'll see the image or background image
File / Video FileAny div elementWill output a video player of the file
Date / Date TimeAny text elementWill output the date/date time in the current browser format
Dimension / Volume / WeightAny text elementWill output the selected value
MoneyAny text elementWill output the money using the Shopify currency format
True or FalseAny elementWill hide/show the element based on that value
List of Single Line TextAny text elementWill show all texts concatenated by a comma. Change the separator using separator=",". If you use separator="repeat", the element itself will be repeated
List of File / Generic FileAny link elementThe link element will be duplicated once for each file. The text content will be the "alt" of the file and the link will be connected to the file link
List of File / Image FileAny image elementThe image element will be duplicated once for each file

Additional Attribute for Single Line Text:

Only for fields of type Single Line Text, you can use an additional attribute:

NameValue
data-attrattribute-to-modify

This will output the value inside the specified attribute instead of setting the value as the text of the element.

Example:

NameValue
data-attrdata-id

This will set the value of the field in the data-id attribute of the element.

Fields Visibility​

Learn how to show or hide elements based on whether a field exists and what its value is.

Basic Visibility Attributes​

To control visibility of an element, use these custom attributes:

Show if field exists:

NameValue
if-metaobjectfield_key

This attribute will show the element if the field exists, with 2 exceptions:

  • For fields of type True / False: It will be shown if the field is set and is set as True
  • For fields of type Integer Number: The element will be shown if the metafield is set and the value is higher than 0

Hide if field exists:

NameValue
unless-metaobjectfield_key

This attribute acts in the opposite way - the element will show only if the metafield doesn't exist.

Check for Value​

By default, metafield visibility attributes will just check for the existence of the metafield. If you wish to check for the value inside the metafield, add also the attribute:

NameValue
data-check-valueDesired Value

Example:

If you created a field of type Single Line Text with key my_option and you want to show an element only when the metafield value is "Option 1", use:

NameValue
if-metaobjectmy_option
data-check-valueOption 1

Single Metaobject​

Load a specific metaobject directly from Shopify for use in specific contexts.

When to Use Single Metaobject​

Use single metaobjects when you need:

  • Specific, structured data for a particular context
  • To enhance the Vendor Page with brand information
  • Dynamic banner/CTA sections controlled from Shopify
  • Product-specific content like size charts, ingredients, FAQs (though Product Metafields may be more appropriate for product-specific cases)

How to Fetch a Metaobject from Shopify​

Step 1: Copy the Component​

  1. Copy the Metaobject component from Smootify
  2. This component loads a single metaobject from Shopify

Step 2: Customize the Attributes​

On the Custom Element smootify-metaobject, modify the following Custom Attributes:

Type:

NameValue
data-typemetaobject_type_to_load

For example, if you created a Metaobject definition with type "testimonials", use:

NameValue
data-typetestimonials

Handle:

You must modify the attribute:

NameValue
data-handlemetaobject_handle

With the handle of the specific metaobject you want to load.

Note: You can naturally bind the value to a CMS value if needed.

Step 3: Add the Metaobject Attributes​

On any Webflow static element you added inside the smootify-metaobject custom element, you can add the attribute:

NameValue
metaobjectmetaobject_field_key

This binds that static element to the corresponding field defined for the metaobject.

Supported Fields​

The supported fields are identical to those listed in the Metaobject Listing section above. Refer to that section for the complete list.

Fields Visibility​

The fields visibility attributes work the same way as described in the Metaobject Listing section. Refer to that section for details.

Example Use Cases​

Enhance the Vendor Page:

  • Load a single metaobject of type "brand" on the Webflow Vendor template page
  • Add different fields controlled directly from Shopify without tampering with the Webflow CMS

Banner:

  • Create a CTA section in Webflow with dynamic content loaded directly from Shopify
  • Allow the store owner to dynamically change a promo section without going into Webflow

Product-Specific Cases:

  • For product-specific metaobjects like Size Charts, List of ingredients, FAQs, etc., consider using Product Metafields instead, which may be more appropriate for those use cases.

Domain Configuration​

Proper domain configuration is critical for headless stores. Incorrect setup will break checkout functionality.

Configuration Rules​

Critical: To use the headless channel, you must set up different domains on Shopify and Webflow. If you attach both domains to Shopify and Webflow, checkout will not work, as the page would be intercepted by Webflow hosting.

Configuration:

  • Main domain (e.g., www.mysite.com) → Webflow only
  • Subdomain (e.g., store.mysite.com) → Shopify only

Step-by-Step Domain Setup​

1. Attach Main Domain to Webflow​

  • The main domain like www.mysite.com must be connected only and exclusively to Webflow
  • Use www as the default in Webflow since most common domain registrars do not support CNAME flattening, ALIAS, or ANAME records
  • Webflow documentation: Domain Setup Guide

2. Detach Main Domain from Shopify​

  • If your main domain (e.g., www.mysite.com) was previously attached to Shopify, you must detach it
  • Otherwise, your checkout will not work since the URL will be intercepted by Webflow server
  • Shopify documentation: Managing Domains

3. Attach Subdomain to Shopify​

  • Even though you can use the default .myshopify.com URL for checkout, it's better for customer trust to see checkout on a URL that belongs to your domain
  • Use a subdomain on your Shopify store like store.mystore.com
  • Shopify documentation: Adding Domains

Domain Provider Considerations​

The exact configuration depends on your domain provider, but ensure:

  • Main domain points to Webflow
  • Subdomain points to Shopify
  • DNS records are correctly configured
  • Allow time for DNS propagation (can take up to 48 hours)

Shopify Redirect Theme​

If you don't want to use the Online Store channel on your Shopify store, install the Smootify Redirect Theme.

Purpose​

The redirect theme redirects all pages of the Online Store to the Webflow site, except the Cart page. This is useful when you must use an app embed that works only on the Online Store on the cart page (like pickup apps).

Additional Features​

The theme has 2 additional settings that you can customize:

  • products_base: Allows correct redirection of product pages according to collection slugs used in Webflow
  • collections_base: Allows correct redirection of collection pages according to collection slugs used in Webflow

This eliminates the need for additional 301 redirects.

Setup​

Step 1: Download the Theme​

  1. Download the Smootify Redirect Theme
  2. The theme is a mix of the official Hydrogen Redirect theme and Dawn theme

Step 2: Install the Theme​

  1. Navigate to Online Store → Themes in your Shopify admin
  2. Upload the theme file you downloaded

Step 3: Configure the Theme​

  1. From Online Store → Themes, press Customize
  2. Navigate to Theme settings → Storefront
  3. Configure the following options:
SettingValueExample
storefront_hostnameThe domain attached to your Webflow projectwww.yourdomain.com (include www to avoid double redirect)
products_baseThe slug of your Product CMS collection in Webflowproduct
collections_baseThe slug of your Collection CMS collection in Webflowcollection

Step 4: Publish​

  1. Publish the theme
  2. All traffic from Online Store will now redirect to your headless Webflow site

Integration Best Practices​

Pre-Launch Checklist​

Use this comprehensive checklist before launching your store:

Webflow​

  • Designed all pages
  • Optimized assets (images, videos, etc.)
  • Configured SEO (meta titles, descriptions, Open Graph)
  • Configured cookie banner
  • Configured analytics integrations (GA4, GTM, etc.)
  • (Optional) Configured Smootify Settings
  • Project transferred to the client
  • Main domain correctly configured

Shopify​

  • Store transferred to the client
  • Payments and taxes settings configured
  • Subdomain connected to Shopify (e.g., store.domain.com)
  • Installed Headless Sales channel
  • Generated a Storefront Token (live token, not development)
  • (Optional) Configured Customer Accounts
  • Removed password protection

Smootify​

  • Shared site with the customer
  • Added the previously generated storefront token into site settings
  • Correctly added the live domain into site settings

Development Setup Checklist​

For initial development:

  • Install Smootify app (Shopify or Webflow)
  • Install Shopify Headless App on Shopify store
  • Create Storefront API connection
  • Enable all Storefront API permissions
  • Copy development token to Smootify dashboard (for testing)
  • Connect Webflow project in Smootify dashboard
  • Create required CMS collections in Webflow
  • Configure custom code settings
  • Test product sync
  • Test checkout flow (in development mode)

Performance Optimization​

  1. Cache Duration: Set appropriate cache duration based on how frequently product data changes
  2. Preload Products: Enable idle-time preloading for better perceived performance
  3. Image Optimization: Ensure product images are optimized in Shopify
  4. Lazy Loading: Use Webflow's native lazy loading for product images

Analytics Integration​

  • Enable Auto Analytics Tracking: Automatically tracks ecommerce events
  • Custom Events: Use Smootify APIs to track custom events
  • Integration with GTM: Smootify events can be captured by Google Tag Manager

Localization​

  • Market Selection: Enable browser language-based market selection
  • Price Formatting: Format prices based on browser settings for better UX
  • Currency Handling: Ensure Shopify markets are configured correctly

Variant Management​

  • Variant Images: Enable "Show only images of currently selected variant" for better UX
  • Variant Selection: Ensure variant selection elements are properly configured in Webflow

Troubleshooting​

Order Confirmation Emails Not Sending​

  • Verify Shopify Headless App is installed
  • Critical: Ensure you're using a live token (not the development token)
  • Check Storefront API permissions are enabled
  • Verify public token is correctly configured in Smootify dashboard
  • Check Shopify email settings
  • Verify the token was generated through the Headless sales channel, not automatically by Smootify

Checkout Not Working​

  • Verify domain configuration: main domain on Webflow, subdomain on Shopify
  • Check that main domain is detached from Shopify
  • Verify subdomain is correctly attached to Shopify
  • Check DNS propagation (can take up to 48 hours)
  • Ensure redirect theme is installed if using Online Store channel

Products Not Syncing​

  • Verify Webflow CMS collections are created with correct slugs
  • Check collection slugs match Smootify configuration
  • Verify Shopify store connection is active
  • Check Smootify dashboard for sync errors

API Not Available​

  • Ensure you're using the smootify:loaded event listener
  • Check browser console for errors
  • Verify Smootify script is loaded on the page
  • Use smootify-load script type for external scripts

Custom Code Not Working​

  • Verify script is wrapped in smootify:loaded event listener
  • Check browser console for JavaScript errors
  • Verify configuration options are correct
  • Test with customizer-generated script first, then modify

Official Resources​


  • Shopify: Ecommerce backend that powers Smootify
  • Webflow: Design platform where Smootify integrates
  • Google Tag Manager: For tracking Smootify ecommerce events