Skip to main content
The JavaScript API works on every ABConvert plan. Reading a test price needs a plan that includes price tests, and reading shipping rates needs a Shopify plan with the Carrier Service API. See Pricing for the full matrix.
window.ABConvert is a JavaScript object on every storefront page. It tells your code which test group the visitor is in, and the test price, shipping rates, and offer that visitor sees. Use it for two jobs:
  • Keep your storefront consistent with the test. Show or hide content by test group, or show the test price, shipping rate, or offer in an element ABConvert does not change.
  • Send the visitor’s test group to your other tools. Segment by test group in a tag manager, a data platform, or a session recording tool.
  • Record a custom event. Call track when a visitor completes an action you measure.
This page is for developers who write storefront JavaScript. The JavaScript API is read-only, and it is not present on checkout pages. Worked scripts for each job are on JavaScript API examples.

Terminology

This page uses the following terms:
  • Test ID is the numeric ID shown in the ABConvert admin, as a string: '49603'. In code it is experimentId: method and field names say experiment for a test.
  • Test group is one of the groups a test splits visitors into. Each test group has an index, which identifies it, and a name, a label you can change at any time. One test group is Control, which sees the store unchanged.
  • Assignment is the test group ABConvert put the visitor in. Reading it never creates one.
  • Ready is the moment every assignment on the page is known. Read assignments only after ready; Step 1 shows how to wait for it.
  • Combined test runs several changes as one test, so the visitor holds one assignment for it.
  • Personalization shows one version to an audience, with one test group.
  • Product variant is the Shopify catalog object. Product, product variant, and collection IDs are numeric strings, as in Liquid: '47522361606401', not 'gid://shopify/ProductVariant/47522361606401'.
  • Store currency is the currency in your Shopify store settings, for example USD. A market can sell in another currency instead: one currency for the whole market, or each country’s local currency.
  • Page currency is the currency this page shows prices in: the store currency, or the market’s currency where a market sets one.

Confirm ABConvert is loaded

window.ABConvert needs no installation step. The ABConvert app embed adds it to every storefront page except checkout. If you installed ABConvert manually, the snippet in theme.liquid does the same. To confirm window.ABConvert exists, run the following in your storefront’s browser console after the page has loaded:
If the result is 'undefined', the ABConvert app embed is off in your theme, or your store runs an older version of the ABConvert storefront scripts. Turn on the app embed; if it is already on, contact support.

Quick start

Step 1: Wait for ABConvert to be ready

Add this to your theme:
window.ABConvertQueue is an array of callbacks. ABConvert runs each one when it is ready, which means every assignment is known and every method works. This works whatever order the scripts load in:
  • The first line creates the array if ABConvert has not yet.
  • Your callback receives the ABConvert object as its argument.
  • Callbacks run in the order you push them. A callback pushed after ready runs at once.
ABConvert is ready after the page has parsed, so your callback can find any element the theme rendered. The visitor may already see that element before your callback changes it. To avoid the flash, hide the element in your theme’s CSS and show it from the callback, once it holds the right content. A callback that throws, or an async callback that rejects, does not stop the callbacks after it. ABConvert logs the error to the browser console with an [ABConvert] prefix. ABConvert also fires abconvert:ready on window at the same moment, once per page load. A listener added after it fired never runs, so prefer the queue. See Events.

Step 2: Read the visitor’s assignments

getAssignments() returns one Assignment per test the visitor is in. On a page with a running test, the snippet above logs something like:
testGroup is the test group this visitor is in. Most scripts branch on it. reason says how the visitor got into that test group; see Assignment.

Assignments

These methods tell you which test group the visitor landed in, per test. They never describe a test the visitor is not in.

Read every assignment

getAssignments() returns an array with one Assignment per test the visitor is in. The array omits tests that excluded the visitor by traffic allocation, audience targeting, or targeting rules, and is empty when the visitor is in no test.

Read one assignment by test ID

getAssignment(experimentId) returns one Assignment, or null when the visitor is not in that test. Find the ID in the ABConvert admin or in the REST API’s List tests response.

Show content to visitors outside Control

Check for null first, then branch on testGroup.control. A visitor who is not in the test gets null, so the banner stays hidden:
To send assignments to a tag manager, a data platform, or a session recording tool, see JavaScript API examples.

Prices

A price test changes product variant prices per test group. ABConvert rewrites the price elements your theme renders on product and collection pages. Use the price methods for a price ABConvert does not change: a custom promo block, a bundle builder, a quick-view card. The price methods need a running price test. They return the test price for the visitor’s test group. A test price is set in your store currency. A multi-market price test can also set a price per market, in the currency that market sells in. A visitor gets their market’s price when you set one, and the store-currency price otherwise. A market price is fixed when you set it. If your store later shows a different price in that market, for example after an exchange rate change, ABConvert stops changing the price there: the visitor sees and pays your store’s price. The methods still return the price you set. They return null in the following cases, and null always means “leave the theme’s price alone”:
  • No price test covers the product or product variant.
  • The visitor is in no price test.
  • The test does not run in the visitor’s market: the market is outside the test, or it sells in another currency and you set no test price for it. The visitor sees your store’s normal price, and still holds an assignment.
A personalization that changes prices reports its price the same way.

Read the visitor’s price for a product variant

getPriceByVariantId(variantId, options?) returns the price of one product variant for this visitor, in the market the page rendered for. The result names that market’s country in country and its currency in currency.
options is optional: country reads another country’s price, and aggregate applies to getPriceByProductId only. Both are described below. amount is a number, so you can do math on it. formatPrice(amount, currency) formats it for the visitor’s locale:

Read the price for another country

Pass country to read the price a visitor from that country gets. The same null rules apply.

Read a product’s price for a collection card

getPriceByProductId(productId, options?) returns one price for a product, in the same market and with the same country option as getPriceByVariantId. aggregate picks which product variant’s price:
To rewrite your own price elements and keep them right as the page changes, see Render a custom price element.

Shipping

A shipping test changes the shipping rates visitors in a test group see at checkout. Use the shipping methods to show those rates before checkout, for example in a “spend $X more for free shipping” bar. The shipping methods need a shipping test running. They return null when the visitor is in no shipping test. A test group with no rates gets [] from getShippingRates() and null from getFreeShippingThreshold(). Shopify picks the shipping zone at checkout from the shipping address, so the browser does not know the visitor’s zone. The methods return rates for every zone, each tagged with its zone, and the zone option narrows them to one. Every rate carries the currency you set it in, which can differ from the page currency, and ABConvert does not convert it. Before you use an amount, compare currency with the cart’s currency, as the free shipping progress bar example does.

Read the visitor’s shipping rates

getShippingRates(options?) returns the rates the visitor’s test group offers, cheapest first within each zone and currency. One zone can hold rates in more than one currency. Pass zone for one zone; the method returns [] for a zone the test does not have:

Read the free shipping threshold

getFreeShippingThreshold(options?) returns the lowest order subtotal at which the visitor’s test group gets a free rate in a zone. Pass zone when the visitor’s shipping tests cover more than one zone. The method returns null when:
  • zone is missing and the tests cover more than one zone.
  • The zone has no free rate.
  • The zone’s only free rates depend on weight. A weight condition has no subtotal to report.
  • The zone’s free rates use more than one currency. No single lowest amount exists.
To render the bar and keep it current as the cart changes, see Render a free shipping progress bar.

Offers

An offer test gives a test group a discount: an amount off products or the order, a shipping discount, or a volume or threshold discount. Use the offer method to show the visitor’s offer in your own banner or table. The offer method exists only while an offer test is running or in preview.

Read the visitor’s offers

getOffers() returns one Offer per offer test the visitor is in. A test group with no offer contributes no Offer, so an empty array means “show nothing.”
discounts lists the offer’s discounts; see Offer. The JavaScript API does not compute tier progress: to show “add 1 more to save 20%”, compare tiers with the cart. To show the offer and the visitor’s progress toward the next tier, see Render an offer banner.

Track custom JS events

A custom JS event is an action you record from your own code, for example a completed product builder. track(name, payload?) records one. name is the event’s slug from the custom event library; payload.value is an optional value.
ABConvert records an event at most once per page load. It ignores an unknown slug, and a call on a page outside the event’s page scope.

Common mistakes

The following patterns break storefront scripts:
  • Writing a price when the method returns null. null means the test does not price this product variant for this visitor. The fix: leave the theme’s price alone.
  • Writing a value that is already correct. ABConvert watches the page for changes, so every write you make restarts its scan. If you watch the page with your own observer, an unconditional write fires it again, loops, and freezes the tab. The fix: compare before you write, as every example does.
  • Polling for ABConvert with a timer. The fix: push your callback onto window.ABConvertQueue; it runs as soon as ABConvert is ready.
  • Using testGroup.name as an identifier. The name is a display label that can change while the test runs. The fix: send testGroup.index to other tools and branch on testGroup.control in your code.
  • Passing a product ID to getPriceByVariantId. It takes the product variant ID and returns null for anything else. The fix: use getPriceByProductId for a product-level price.

Force a test group

To see one test group yourself, force it from the console. Do not force in production code. A forced assignment is left out of results and carries reason: 'url_force_assign'. forceTestGroup(experimentId, index) puts you in a test group from the next page load, and clearForcedTestGroup(experimentId) undoes it. The force stays with the browser tab until you clear it or close the tab. An index past the last test group shows Control:
To force a test group with a link instead, see See one test group with a link.

Reference

Every global, method, event, and object is on JavaScript API reference.

FAQ

In the browser console, run typeof window.ABConvert after the page has loaded. If the console shows 'object' but your script sees undefined, your script ran before ABConvert loaded: push your callback onto window.ABConvertQueue. If the console also shows 'undefined', either the app embed is off or your store runs an older version of the ABConvert storefront scripts; see Confirm ABConvert is loaded.
First check that you passed the product variant ID, not the product ID. Otherwise null means no test price applies to this visitor; see Prices. Leave the theme’s price alone.
Call getShippingRates() to list every zone. If more than one zone comes back, pass zone. If the zone has no amount: 0 rate, or its only amount: 0 rate has a weight condition, no threshold exists. If the zone’s free rates are in more than one currency, no single threshold exists: read the rates for the cart’s currency from getShippingRates() instead.
ABConvert catches an error thrown or rejected inside a window.ABConvertQueue callback, so the callbacks after yours still run. Look for a console line that starts with [ABConvert]: it carries your error and its stack.
No. The JavaScript API is read-only. ABConvert attributes conversions and revenue from Shopify orders.