# JavaScript API

> The methods, events and filters of window.Smootify.

Status: Ready (Smootify 2.0)  
URL: https://www.smootify.io/docs/reference/api  
Updated: 2026-10-13

## At a glance

- **Methods** (`window.Smootify`, [JavaScript API](https://www.smootify.io/docs/developers/javascript-api)): your code asks and Smootify answers. Use them to read the cart, the products, the customer or the market, add to the cart, open the mini cart. For example `getCart()`, `addToCart()`, `getCustomer()`. Call them from a `push` function; most return a Promise.
- **Events** (`Smootify.on`, [Events](https://www.smootify.io/docs/developers/events)): Smootify reports what happened. Use them to keep your own counter in sync, track additions, start analytics after consent. For example `cart_updated`, `added_to_cart`, `consent_changed`. What the handler returns is ignored; `once` stops after the first event.
- **Filters** (`Smootify.addFilter`, [Filters](https://www.smootify.io/docs/developers/filters)): Smootify hands a value to your function before it uses it. Use them to check or enrich the lines added to the cart, change the checkout address or a draft order, choose the metafields the page asks for. For example `add_to_cart_lines`, `checkout_url`. Answer the value changed, nothing to keep it, or `false` to stop.
- **AJAX API** (`/cart.js`, [Shopify AJAX API](https://www.smootify.io/docs/developers/ajax-api)): for apps written for Shopify themes. An app's snippet runs as it is: Smootify answers the theme endpoints on the page, with a theme's JSON. For example `/cart.js`, `/cart/add.js`, `/products/{handle}.js`. Same cart as the page; start the snippet with `type="smootify-load"`.

More in [the guide](https://www.smootify.io/docs/developers/javascript-api).

Queue your code with `window.Smootify = window.Smootify || []; window.Smootify.push((api) => { … })`: it runs once Smootify knows the visitor and the market, before it loads products and the cart, so listeners get every event and filters apply from the first request.

## Methods

| Method | What it does | |
|---|---|---|
| [`Smootify.push()`](https://www.smootify.io/docs/reference/api/methods/push) | runs each function once Smootify knows the visitor and the market, before it loads products and cart, so listeners get every event and filters apply from the first request; right away later on. One that throws does not stop the others. | new in 2.0 |
| [`Smootify.on()`](https://www.smootify.io/docs/reference/api/methods/on) | listens to an event; `replay` also calls the handler with the last payload of one that already happened. Returns the unsubscribe. | new in 2.0 |
| [`Smootify.once()`](https://www.smootify.io/docs/reference/api/methods/once) | — | new in 2.0 |
| [`Smootify.addFilter()`](https://www.smootify.io/docs/reference/api/methods/addfilter) | adds a filter after the ones added before it; returns its removal | new in 2.0 |
| [`Smootify.getCart()`](https://www.smootify.io/docs/reference/api/methods/getcart) | — | — |
| [`Smootify.getCartID()`](https://www.smootify.io/docs/reference/api/methods/getcartid) | — | — |
| [`Smootify.addToCart()`](https://www.smootify.io/docs/reference/api/methods/addtocart) | adds lines (through the `add_to_cart_lines` filters): resolves with the cart, or with Shopify’s errors | — |
| [`Smootify.addBoxToCart()`](https://www.smootify.io/docs/reference/api/methods/addboxtocart) | adds lines as one Magic Box, with its title, image and discount percentage (`___dp`) | — |
| [`Smootify.updateCartLines()`](https://www.smootify.io/docs/reference/api/methods/updatecartlines) | rejects with Shopify’s errors | — |
| [`Smootify.removeCartLines()`](https://www.smootify.io/docs/reference/api/methods/removecartlines) | `dispatchEvents: false` changes the cart without events or re-render (1.x) | — |
| [`Smootify.clearCart()`](https://www.smootify.io/docs/reference/api/methods/clearcart) | — | — |
| [`Smootify.reloadCart()`](https://www.smootify.io/docs/reference/api/methods/reloadcart) | asks Shopify for the cart again | — |
| [`Smootify.applyCouponCode()`](https://www.smootify.io/docs/reference/api/methods/applycouponcode) | resolves with the cart, or with Shopify’s errors | — |
| [`Smootify.removeCouponCode()`](https://www.smootify.io/docs/reference/api/methods/removecouponcode) | rejects with Shopify’s errors | new in 2.0 |
| [`Smootify.applyGiftCard()`](https://www.smootify.io/docs/reference/api/methods/applygiftcard) | resolves with the cart, or with Shopify’s errors | — |
| [`Smootify.removeGiftCard()`](https://www.smootify.io/docs/reference/api/methods/removegiftcard) | the id is the applied gift card’s (`cart.appliedGiftCards[].id`); rejects with Shopify’s errors | new in 2.0 |
| [`Smootify.updateCartNote()`](https://www.smootify.io/docs/reference/api/methods/updatecartnote) | — | new in 2.0 |
| [`Smootify.updateCartAttributes()`](https://www.smootify.io/docs/reference/api/methods/updatecartattributes) | — | new in 2.0 |
| [`Smootify.checkout()`](https://www.smootify.io/docs/reference/api/methods/checkout) | goes to checkout, as the cart’s checkout button, after the `checkout_url` filters; rejects with the errors | new in 2.0 |
| [`Smootify.openCart()`](https://www.smootify.io/docs/reference/api/methods/opencart) | opens the page’s mini cart (not a cart page) | new in 2.0 |
| [`Smootify.closeCart()`](https://www.smootify.io/docs/reference/api/methods/closecart) | — | new in 2.0 |
| [`Smootify.getCartAsDraftOrderData()`](https://www.smootify.io/docs/reference/api/methods/getcartasdraftorderdata) | the cart as a draft order input (Draft Orders) | — |
| [`Smootify.getProductsById()`](https://www.smootify.io/docs/reference/api/methods/getproductsbyid) | the products by id that Shopify knows in the current market | — |
| [`Smootify.getProductByHandle()`](https://www.smootify.io/docs/reference/api/methods/getproductbyhandle) | — | new in 2.0 |
| [`Smootify.selectVariant()`](https://www.smootify.io/docs/reference/api/methods/selectvariant) | selects a variant (its number or gid) of a `smootify-product` of the page: the element, or one inside it; false when the product has no such variant | new in 2.0 |
| [`Smootify.toast()`](https://www.smootify.io/docs/reference/api/methods/toast) | shows the page’s `[toast="<name>"]` (in `smootify-toasts`) with `items` written into its `[toast-item]` children, as `Smootify.toast("added-to-cart", { title: "Gift wrap" })`; false when the page has no such template | new in 2.0 |
| [`Smootify.isLoggedIn()`](https://www.smootify.io/docs/reference/api/methods/isloggedin) | — | new in 2.0 |
| [`Smootify.getCustomer()`](https://www.smootify.io/docs/reference/api/methods/getcustomer) | the customer (null for a guest) once the session is known | new in 2.0 |
| [`Smootify.passwordlessLogin()`](https://www.smootify.io/docs/reference/api/methods/passwordlesslogin) | starts the login of Shopify’s customer accounts | — |
| [`Smootify.logout()`](https://www.smootify.io/docs/reference/api/methods/logout) | ends the session, and Shopify’s too | new in 2.0 |
| [`Smootify.getNewCustomerAccessToken()`](https://www.smootify.io/docs/reference/api/methods/getnewcustomeraccesstoken) | the Customer Account API token of the session ("" for a guest) | — |
| [`Smootify.queryCustomer()`](https://www.smootify.io/docs/reference/api/methods/querycustomer) | a Customer Account API query on the customer: `fields` is the selection inside `customer { … }` | — |
| [`Smootify.setCustomerMetafields()`](https://www.smootify.io/docs/reference/api/methods/setcustomermetafields) | — | — |
| [`Smootify.getLocalization()`](https://www.smootify.io/docs/reference/api/methods/getlocalization) | country, currency, language and where the store sells, once known | new in 2.0 |
| [`Smootify.changeCountryByIsoCode()`](https://www.smootify.io/docs/reference/api/methods/changecountrybyisocode) | true when the country changed (the page follows it) | — |
| [`Smootify.changeMarketLanguage()`](https://www.smootify.io/docs/reference/api/methods/changemarketlanguage) | — | — |
| [`Smootify.formatMoney()`](https://www.smootify.io/docs/reference/api/methods/formatmoney) | an amount in the store’s money format; `forceNoHtml` and `forceNoTaxes` are accepted and ignored (1.x) | — |
| [`Smootify.getConsent()`](https://www.smootify.io/docs/reference/api/methods/getconsent) | the visitor’s consent; loads Shopify’s Customer Privacy script when the page has not yet | new in 2.0 |
| [`Smootify.setConsent()`](https://www.smootify.io/docs/reference/api/methods/setconsent) | — | new in 2.0 |
| [`Smootify.enableAnalytics()`](https://www.smootify.io/docs/reference/api/methods/enableanalytics) | 1.x: Shopify’s analytics with (`true`) or without the visitor’s consent | — |
| [`Smootify.query()`](https://www.smootify.io/docs/reference/api/methods/query) | a Storefront API query in the current market: resolves with `data`, rejects with the GraphQL errors | — |

## Events

| Event | When | |
|---|---|---|
| [`smootify:loaded`](https://www.smootify.io/docs/reference/api/events/loaded) | Smootify is loaded: the API answers, the session, the market and the cart are known (once per page) | — |
| [`smootify:product_loaded`](https://www.smootify.io/docs/reference/api/events/product-loaded) | a product was loaded; null for an id that is not published on the Headless channel or in the market | — |
| [`smootify:product_expired_load`](https://www.smootify.io/docs/reference/api/events/product-expired-load) | a product shown from the cache changed on Shopify: this is the fresh one | — |
| [`smootify:loadedAdditionalVariants`](https://www.smootify.io/docs/reference/api/events/loadedadditionalvariants) | the product page’s product with every variant, when it has more than 250 | — |
| [`smootify:added_to_cart`](https://www.smootify.io/docs/reference/api/events/added-to-cart) | lines were added, after the cart came back: once per add to cart, a product with its add-ons included (the main line first); when the add-ons fail, the main line that went in alone | — |
| [`smootify:removed_from_cart`](https://www.smootify.io/docs/reference/api/events/removed-from-cart) | the ids of the removed lines | — |
| [`smootify:cart_updated`](https://www.smootify.io/docs/reference/api/events/cart-updated) | every change of the cart, the first load included | — |
| [`smootify:errors`](https://www.smootify.io/docs/reference/api/events/errors) | Shopify’s errors of a cart operation, or the error a filter threw | — |
| [`smootify:initiate_checkout`](https://www.smootify.io/docs/reference/api/events/initiate-checkout) | the visitor goes to checkout | — |
| [`smootify:user_auth_change`](https://www.smootify.io/docs/reference/api/events/user-auth-change) | the session is known or changed: the customer, null for a guest | — |
| [`smootify:filter_initial_change`](https://www.smootify.io/docs/reference/api/events/filter-initial-change) | a filter Search & Discovery applied from `selected-value` or the url, before the first search | — |
| [`smootify:filter_changed`](https://www.smootify.io/docs/reference/api/events/filter-changed) | the visitor changed a filter (`name: "query"` for the search text) | — |
| [`smootify:sort_changed`](https://www.smootify.io/docs/reference/api/events/sort-changed) | — | — |
| [`smootify:changed_option`](https://www.smootify.io/docs/reference/api/events/changed-option) | the visitor changed an option of a product (not at the first render) | — |
| [`smootify:changed_country`](https://www.smootify.io/docs/reference/api/events/changed-country) | — | — |
| [`smootify:created_address`](https://www.smootify.io/docs/reference/api/events/created-address) | a `create-address` form saved an address | — |
| [`smootify:wishlist:changed_variant`](https://www.smootify.io/docs/reference/api/events/wishlist-changed-variant) | `wishlist-toggle[data-use-variants]`: the toggle follows another variant | — |
| [`smootify:wishlist:changed_variant_state`](https://www.smootify.io/docs/reference/api/events/wishlist-changed-variant-state) | — | — |
| [`smootify:wishlist:changed_product`](https://www.smootify.io/docs/reference/api/events/wishlist-changed-product) | — | — |
| [`smootify:wishlist:changed_product_state`](https://www.smootify.io/docs/reference/api/events/wishlist-changed-product-state) | the visitor added (`active`) or removed a product | — |
| [`smootify:color_patterns`](https://www.smootify.io/docs/reference/api/events/color-patterns) | 1.x only: 2.0 has no global color patterns and never dispatches it | never dispatched in 2.0 |
| [`smootify:cart_opened`](https://www.smootify.io/docs/reference/api/events/cart-opened) | a mini cart (dialog, details, dropdown, popover, custom) opened | new in 2.0 |
| [`smootify:cart_closed`](https://www.smootify.io/docs/reference/api/events/cart-closed) | — | new in 2.0 |
| [`smootify:consent_changed`](https://www.smootify.io/docs/reference/api/events/consent-changed) | the visitor’s consent once it is known on the page, then at every change | new in 2.0 |
| [`smootify:variant_changed`](https://www.smootify.io/docs/reference/api/events/variant-changed) | a product’s variant changed after its first render (`element` is the product on the page) | new in 2.0 |

Events dispatched on the element instead of `document`: `productLoaded`, `changeVariant`, `changePlan`, `smootify:product_reload`, `smootify:reload`, `imageChanged`, `quantityChanged`, `addon:state_change`, `sm:add_to_cart:connected`, `smootify:price_render`, `smootify.renderedMetafields`, `custom:toggle`.

## Filters

| Filter | What it changes |
|---|---|
| [`add_to_cart_lines`](https://www.smootify.io/docs/reference/api/filters/add-to-cart-lines) | The lines about to be added to the cart: the add to cart forms (the main line and its add-ons at once), boxes, direct add, buy again, `addToCart`, `addBoxToCart` and `/cart/add.js`. The message of an error a filter throws shows in the form and goes out with `smootify:errors`. |
| [`checkout_url`](https://www.smootify.io/docs/reference/api/filters/checkout-url) | Where the visitor goes to check out: the checkout url (or the invoice of a draft order), from the cart’s checkout button, a buy now or `Smootify.checkout()`. Answer another url (parameters added, another checkout) or `false` to keep the visitor here (terms not accepted, a minimum order); the message of an error a filter throws shows in the cart. `smootify:initiate_checkout` goes out only when the visitor leaves. |
| [`draft_order_data`](https://www.smootify.io/docs/reference/api/filters/draft-order-data) | The draft order about to be created (Draft Orders, server plan): a quote, or a checkout or buy now with a custom price. An error a filter throws shows in the cart or the form. |
| [`metafield_definitions`](https://www.smootify.io/docs/reference/api/filters/metafield-definitions) | The metafields the products and the cart ask Shopify for, for each kind of `[metafield]` element on the page (add the ones a script reads, remove the ones nobody shows). Synchronous: it cannot stop, and an error it throws is logged and the filter skipped. |
