Skip to main content
When using the app embed (recommended), the embed loads the SDK and provides storefront credentials and customer context automatically. Set window.SwishOptions before the embed runs to customize behavior and appearance:
For headless storefronts or manual setups without the app embed, call createSwish() directly with the full options object including storefront and context. See the quickstart for both approaches.
The sections below document every available option. All options can be passed via window.SwishOptions or directly to createSwish().

storefront

Credentials for the Shopify Storefront API. The SDK uses these to load product data, images, and recommendations.
string
required
Your .myshopify.com domain (e.g. my-store.myshopify.com). This is the same value as context.myshopifyDomain.
string
required
A Shopify Storefront API access token with read access to products.
The Storefront API access token is not generated automatically - you need to create one in your Shopify admin.
  1. Go to Settings > Apps and sales channels > Develop apps.
  2. Create a new app (or select an existing one).
  3. Under Configuration, enable the Storefront API and grant at minimum the unauthenticated_read_product_listings scope.
  4. Install the app and copy the Storefront API access token from the API credentials tab.
For headless storefronts, store the token in an environment variable (e.g. NEXT_PUBLIC_SHOPIFY_STOREFRONT_TOKEN) rather than hardcoding it.

context

Information about the current customer and storefront environment.

Customer

string | null
required
Shopify customer ID, or null for guest visitors.
string | null
required
Customer email address.
string | null
required
Customer first name.
string | null
required
Customer last name.
boolean | null
required
Whether the customer is a B2B customer.
string[] | null
Shopify customer tags. Used to target content blocks at a subset of shoppers. Optional — omit it and tag-targeted blocks simply never match.

Localization

string
required
ISO country code (e.g. "US").
string
required
ISO language code (e.g. "EN").
string
required
Shopify market handle.

Other context

string
required
Your .myshopify.com domain.
string
Your store’s name, as shoppers know it. The drawer header shows it when you have set neither a title nor a logo — see Drawer. On Shopify themes this is shop.name and the app embed passes it for you.
string
The store’s currency format, as set under Settings → General → Currency formatting. Only its decimal placeholder is read: a format using amount_no_decimals (any variant) drops the cents from every price Swish renders. The currency symbol, its position and the thousands separator come from Swish’s own per-currency formats either way. On Shopify themes this is shop.money_format and the app embed passes it for you.
boolean
required
Whether the store uses Shopify’s new customer accounts.
string
required
URL path for the customer account page.
string
default:"/"
Root URL for the storefront. Useful for multi-language stores with prefixed paths.
string
default:"/apps/wishlist"
URL path for the full-page list detail view.

auth

string
default:"/apps/wishlist/api/profiles/token"
URL the SDK calls to create auth tokens. On Shopify themes this is the default app proxy token endpoint. For headless setups, set this to the route where you host the auth proxy.

features

"none" | "save" | "view" | "all"
default:"none"
Require the customer to be signed in to perform specific actions. "save" requires sign-in to save an item, "view" requires sign-in to open the drawer, and "all" requires it for every action Swish can gate, including any gated in a later release. See the Account guide for details.

integrations

Third-party destinations the SDK sends events to from the storefront. The theme sets these through window.SwishOptions; they are not part of the setup yet.
boolean
default:"true"
Send every save to the store’s Meta Pixel as an AddToWishlist event, through the theme’s fbq when the customer allows marketing or, without one, as a swish-add-to-wishlist customer event for a custom pixel to forward. See the Meta Pixel integration.

metafields

Fetch additional Shopify metafields alongside product data. Metafields are specified in namespace.key format. See the Metafields guide for usage examples.
string[]
default:"[]"
Product metafields to fetch.
string[]
default:"[]"
Variant metafields to fetch.

transforms

Transform functions that customize how product, variant, and option data is displayed in the Swish UI. See the Transforms guide for usage examples. A Badge can be a plain string or an object with id, label, and optional style. productImage returns an image object with at least a url, such as one of product.images.nodes. Returning undefined or null keeps defaultImage. recommendations receives and returns product references carrying only id - the recommendations query fetches nothing else, and each card re-fetches full product data per item. It may return a promise, so it’s the one transform that can do async work.
addToCartButton defaults to true, so supply it only to hide cart buttons for particular products - add-to-cart on the product detail view, the buy button on cards, and the quick-buy button. The section options (showBuyButton, showQuickBuyButton) gate the same buttons independently: both the section option and this transform must allow a button for it to render.This transform is per product, not per view, so it cannot keep the product detail button while removing quick-buy from cards. Use ui.productCard.showQuickBuyButton for that.
Only addToCartButton, linkToProductPage, combinedListingParent, and hideOption tolerate a non-function value - a literal such as linkToProductPage: true is wrapped into a constant function. The other transforms are called directly, so passing a non-function (for example productPrice: false) throws on every render.

intents

Behavioral options that control how specific intents interact with the customer.

saveProduct

unsaveProduct

editSavedProduct

initiateQuickBuy

Whether the quick-buy button on a product card adds straight to cart or opens the quick buy dialog. By default, a card that knows its variant, such as an item saved with one, adds that variant to the cart directly without invoking initiate:quick-buy. Cards without a variant always open the dialog. Set to true to open the dialog for every card. initiate:quick-buy invoked from your own code follows the same option.

createCartLine

removeCartLine

saveCartLine

placements

Declare placements upfront so the SDK automatically mounts them at initialization. Each entry uses the same placement spec as swish.placements.create().
After initialization, all configured placements are accessible via swish.placements.list - an array of { spec, mount, unmount } objects you can use to unmount individual placements programmatically. For the full placement spec reference, see Placements.

ui

UI options control the visual layout and behavior of every view in the Swish drawer. Pass view-specific sections arrays to customize the layout. For a detailed guide with examples, see Views.

Global options

Product cards

ui.productCard applies to every product card, in every view. showQuickBuyButton and linkToProductPage have no default - leave one unset and the layer below it decides.
boolean
Whether cards show the quick-buy button (the floating cart button over the card image). Set false to hide it on every card - the saves grid, both list detail views, product recommendations and featured collections - while leaving add to cart on the product detail view untouched. This is the only way to hide quick-buy store-wide without also removing the product detail button, which is what transforms.addToCartButton would do.It is a hard off switch, not a fallback: a section that sets showQuickBuyButton: true cannot re-show the button while this is false. Sections that expose their own toggle can still hide it in just their view.This switch is code-only. In the customiser, you turn quick-buy on per view with that view’s Show quick buy button.
Whether a card is a hard link to its PDP rather than opening the in-drawer product view. It is the only setting for this: no section has its own linkToProductPage. When it is unset, transforms.linkToProductPage decides. The standalone Wishlist page ignores both and always links to the PDP. Set it in the customiser under Global → Preferences → Product cards.
"image" | "title"
default:"\"image\""
Where a card’s save button sits. "image" keeps it over the bottom corner of the card image. "title" moves it beside the product title and price, as a plain icon in the card title colour, outlined until saved and filled once saved. The save button’s On image settings do not apply there. Only the save button moves: quick buy and badges stay on the image. Applies to the drawer and the standalone Wishlist page. Set it in the customiser under Global → Preferences → Product cards → Save button position.

Save button

"none" | "pulse" | "jello" | "particles"
default:"\"none\""
The animation a save button plays when a customer taps it to save an item. "pulse" shrinks the icon and springs it back, "jello" squashes and stretches it, and "particles" bursts small copies of the icon out of it. It plays once the save goes through, never for an item that is already saved, and not at all for customers who turn on reduced motion in their system settings. It applies to every save button: placed buttons, and the hearts in the drawer and on the Wishlist page. A value it doesn’t know plays nothing. Set it in the customiser under Global → Save button → Save animation.

Product badges

ui.badges.rules is the product badge priority list for product cards and the product detail view. Each product shows one badge: the first enabled row, in list order, that applies to it. Set it in the customiser under Global → Preferences → Product badges. The chosen badge then goes through transforms.productBadges as defaultBadges. The list holds Swish’s built-in badges, { type: "sold-out" }, { type: "sale" } and { type: "low-stock" }, and your own { type: "custom" } rows. It defaults to the three built-ins in that order, with Low stock hidden, which is how badges worked before the list existed. A list that leaves a built-in out gets it appended as in the default: Sold out and Sale shown, Low stock hidden. Set enabled: false to hide a built-in, and enabled: true to show Low stock.
"sold-out" | "sale" | "low-stock" | "custom"
required
"sold-out" applies when the product or selected variant can’t be bought, "sale" when its compare-at price is above its price, and "low-stock" when 1 to max units are left. The built-in badges show translated text (productCard.badges.soldOut, productCard.badges.sale, productCard.badges.lowStock), which you change per language in translations. "custom" applies when its condition matches.
boolean
default:"true"
Set false to hide the badge. The next matching row shows instead. The Low stock row defaults to false.
number
default:"5"
Low stock row only. The badge shows when 1 to max units are left. It reads the selected variant when there is one; without one it reads the product’s total stock. It never applies to a sold-out product or a variant selling on backorder. Swish fetches stock levels only while this row is shown.
string
default:"\"\""
The badge text, as plain text. On a custom row it is required: a blank label shows nothing. On a built-in row, blank keeps the translated text and a value replaces it in every language; to change a built-in badge’s text per language, use translations instead. The badge keeps its badge-sold_out / badge-sale / badge-low_stock class either way.
object
Custom rows only. { type: "tag", tag } matches a product tag, ignoring case. { type: "metafield", metafield, operator, value } reads a product metafield named namespace.key. operator is "exists" (any value, the default), "equals" or "contains", all ignoring case. "contains" also matches one item of a list metafield. Swish adds every metafield a row names to metafields.product for you.{ type: "discount", minPercent } applies when the price is at least minPercent below the compare-at price (default 20). It reads the selected variant when there is one, otherwise the product.{ type: "published-within", days } applies for days days after the product was published to your storefront’s sales channel (default 30), so a New badge drops off by itself. It reads the product’s publishedAt date, so every variant of a product shows the same result.
string
default:"\"\""
The badge background. Blank uses the badge colours from ui.design.
string
default:"\"\""
The badge text colour. Blank uses the badge colours from ui.design.

Wishlist

ui.wishlist covers how the wishlist itself works, as opposed to how any one view looks. Set both fields in the customiser under Global → Preferences → Wishlist experience, where experience is Wishlist surface.
"drawer" | "classic-page"
default:"\"drawer\""
"classic-page" replaces the drawer with your standalone wishlist page. Every navigation intent (view:home, view:saves, view:list, …) sends the customer to context.routes.listDetailPagePath instead of opening the drawer, carrying ?list-id= when a list is targeted. It implies multipleLists: false: the save toast drops its Add to list action and unsaving no longer asks which list to remove from.
boolean
default:"true"
Whether customers can keep more than one saved list. With false, the save toast’s action opens ui.defaultView instead of the list picker, and unsaving skips the picker regardless of intents.unsaveProduct.selectList. Reach for it when you want a single list and the drawer, since experience: "classic-page" already implies one on its own. See Single list only.
"home" | "saves" | "lists" | "notifications" | "orders" | "profile"
default:"\"home\""
The view the drawer opens on. view:home resolves to it, so every generic entry point - a swish-intent="view:home" button, a #swish link, the header button - lands there without any theme changes, and so does the save toast’s View action. It is also the drawer’s root: the Back chevron is hidden there, and Back from any other view returns to it. The Home view stays reachable through the footer Home tab; a store running Swish as a pure wishlist sets this to "saves" and turns that tab off. Set it in the customiser under Global → Preferences → Wishlist experience.

Views

Each view accepts a sections array. See Views for the full configuration reference with defaults and examples.

drawer-header

The drawer’s top bar. See Drawer for examples.

ui.drawer.sections[].options

sign-in

The sign-in callout shown to signed-out shoppers. Used by ui.home, ui.saves and ui.lists, each with its own copy. It renders above the rest of the view, so a guest’s own saves and lists stay visible below it, and hidden: true removes it from that view.

ui.home.sections[].options, ui.saves.sections[].options, ui.lists.sections[].options

The standalone Wishlist page’s header: the title, then the page’s actions. Used by ui.listDetailPage only. See the List detail page guide for which actions appear on which view.

ui.listDetailPage.sections[].options

list-items-grid

Renders a list’s items, either as a product grid (layout: "gallery") or as one full-width row per item (layout: "card"). Used by both ui.listDetail (in-drawer) and ui.listDetailPage (standalone full-page). Each view exposes a different subset of options. Card layout puts the image on the left and the vendor, title, price, variant and an Add to cart button on the right. The image renders square in that layout rather than following the Global → Components → Product cards → Card image aspect ratio, so rows stay compact. Neither list detail view exposes layout in the Swish admin, so both render the gallery layout unless you set the option in code. The all-items-grid section below still offers the choice. Neither view has a linkToProductPage option. In the drawer, cards follow ui.productCard.linkToProductPage. The standalone page always links its cards to the PDP.

ui.listDetailPage.sections[].options

ui.listDetail.sections[].options

all-items-grid

Renders the customer’s saved items, either as a product grid (layout: "gallery") or as one full-width row per item (layout: "card"). Used by ui.saves, and by the All Items screen that the grid’s heading links to — both read this one section. Card layout puts the image on the left and the vendor, title, price, variant and an Add to cart button on the right. The image renders square in that layout rather than following the Global → Components → Product cards → Card image aspect ratio, so rows stay compact.

ui.saves.sections[].options

translations

Override default UI strings by language. Keys are language codes, values are objects mapping translation keys to strings.