@abconvert/headless by entry point. For what the SDK is for and how to set it up, read the overview and your stack guide first.
IDs are accepted as the Storefront API returns them, gid://shopify/ProductVariant/47522361606401, or as the number, '47522361606401'. Test IDs are the number the ABConvert admin shows, as a string or a number. Returned IDs, such as Assignment.experimentId, Price.productId, and Price.variantId, are always strings holding the number: '47522361606401'.
Entry points
- Any stack
- Next.js
- Hydrogen 2026.10 and later
- Hydrogen before 2026.10
Entry points
createABConvert
Creates the client. What you pass decides which client you get:Signature
ServerABConvert adds getPageState, isPageTested, and isTesting; PageABConvert adds getPageState. Both are exported, so TypeScript knows which methods your client has.
Never rejects, with one exception: a client made with pageKey rejects when the tests the key names cannot be loaded. When the tests cannot be loaded for a request, the client answers as the original store. See Loading and failures.
Options
string
required
Your
myshopify.com domain: 'your-store.myshopify.com'.string
required
A storefront key from Integrations > Headless Storefront in ABConvert. It tells ABConvert which store’s tests to load, and is safe to ship in storefront code.
Request | { headers, url }
The incoming request. Required on the server. Pass the Fetch
Request, or { headers, url } when your framework has none.string
ISO 3166-1 alpha-2 code of the country your storefront shows prices for, the same value you pass to the Storefront API in
@inContext. Defaults to your store’s default country. See Prices by country.number
default:"1000"
Milliseconds to wait for your tests when the server holds no copy yet. See If loading is slow.
number
default:"60"
Seconds a loaded copy of your tests stays fresh. See How the copy refreshes.
(error: Error) => void
Called when your tests cannot be loaded.
{ analytics: boolean }
Whether the visitor allows analytics. Without it, the SDK reads Shopify’s
_tracking_consent cookie when the visitor has one, and otherwise treats analytics as allowed. See Consent.boolean
default:"false"
true when your storefront loads Shopify’s Customer Privacy API. The SDK then tracks nothing until the visitor answers. The Hydrogen entries set it for you.string
Builds the client from a page key instead of a request:
getPageKey() from the server client, or the segment the Next.js middleware rewrote to. '' is a page no test changes.boolean
default:"false"
true when your product pages show no price but their own product’s. A product page’s key then carries only the price tests that include that product. Leave it unset when a related product’s price appears on the page.A client made with pageKey
A client made withpageKey renders a page a cache may serve to everyone in its test groups, so it has no visitor:
createABConvertrejects when the tests the key names cannot be loaded. It waits up to 10 seconds, ortimeoutif that is longer. An empty key never rejects.- Price and assignment reads answer for the key’s test groups. Shipping rates and offers are not in a page key, so those reads return nothing.
getPageState()replacesgetClientState(), which throws.getCartAttributes(),getCartLineAttributes(), andgetCheckoutUrl()throw. Create a client from the request for them.getVisitorId()returns'',getRedirectUrl()returnsnull, andgetSetCookieHeaders()returns[].
Methods
The server client, the browser client, anduseABConvert() in a component share one API. “Runs on” marks the methods that do something on one side only; elsewhere they return the empty value shown.
getAssignment
Returns the visitor’sAssignment for one test, or null when the visitor is not in it. See Read an assignment.
string | number
required
The test ID shown in the ABConvert admin:
'49603'.getAssignments
Returns oneAssignment per test the visitor is in. [] when they are in none.
getFeature
Coming soon. Returns the visitor’sAssignment in the running feature test with this key, or null. Until feature tests ship it returns null for every key.
string
required
The feature key set on the test:
'home-hero'.getPriceByVariantId
Returns the visitor’sPrice for one product variant, or null when the visitor sees the original price: the product variant is in no price test, or the visitor is not in its test. A visitor in Control gets the original price as a Price. See Show a test price.
string | number
required
The product variant ID.
PriceOptions
getPriceByProductId
Returns aPrice for one product, from its product variants’ prices, or null in the same cases as getPriceByVariantId.
string | number
required
The product ID.
PriceOptions
formatPrice
Returnsamount formatted in currency, such as '$62.70', in the locale the page rendered in, so the server and the browser format alike.
number
required
string
ISO 4217 code:
'USD'. Defaults to your store’s currency.getShippingRates
Returns everyShippingRate the visitor’s test group offers, null when the visitor is in no shipping test, or [] when the test group has no rates or zone names a zone the test does not have. See Show shipping rates and offers.
ShippingOptions
getFreeShippingThreshold
Returns theFreeShippingThreshold the visitor’s test group gets, or null when the visitor is in no shipping test or no single threshold exists.
ShippingOptions
getOffers
Returns everyOffer the visitor’s test group gets. [] when the visitor is in no offer test, or their test group has no offer.
getVisitorId
Returns the visitor ID the SDK keeps in theabconvert-visitor cookie. '' on a client made with pageKey.
getCountry
Returns the country the client prices for: thecountry you passed, or the store’s default.
forceTestGroup
Shows one test group to this visitor, for the rest of the visit. A forced visit is left out of results. On Next.js, a force on the server lasts only for that render. See Preview a test group.string | number
required
The test ID shown in the ABConvert admin.
number
required
The test group’s position counting from 0:
0 is Control, 1 is Variant A.clearForcedTestGroup
UndoesforceTestGroup for one test.
string | number
required
The test ID shown in the ABConvert admin.
getCartAttributes
Returns the cart attributes that make Shopify checkout apply the visitor’s tests: oneCartAttribute per key. Send them with the cart’s own attributes on every cartAttributesUpdate. Throws on a client made with pageKey.
getCartLineAttributes
Returns the same data asCartAttribute entries for a cart line. Add them to each line you add. Throws on a client made with pageKey.
getCheckoutUrl
Returns a Shopify cart permalink that lands in checkout with the visitor’s test groups applied. Build it when you render the button; never share or cache it. Throws on a client made withpageKey. See Checkout URLs.
CheckoutUrlOptions
required
getPageKey
Returns the page key: the test groups this page renders for, the same for every visitor in them.'' when no test changes the page. In the browser, a client built from getPageState() returns the key the page was rendered for, and one built from getClientState() returns ''.
getRedirectUrl
Server only. Returns where a URL redirect test sends this visitor, as a same-origin path, ornull when they stay: they are in Control or outside the test, the URL is not part of a test, or the visitor is a known crawler. null in the browser.
string
required
The URL the visitor requested:
request.url.getClientState
Server only. Returns theClientState that hands this visitor’s page to the browser. It holds the visitor, so a page that carries it renders per visitor and must not be cached. Pass it to the provider’s state. Throws on a client made with pageKey.
getPageState
Server only. Returns thePageState that hands the page to the browser with nothing about the visitor, so a cached page can carry it. From a client made from a request, it carries the tests the client’s reads touched, as the visitor saw them; from a client made with pageKey, the key’s test groups. Pass it to the provider’s pageState.
isPageTested
Server only, on a client made from a request. Returnstrue when a test that runs or is in Preview can change this page for some visitor, whatever this visitor’s test groups: a price test prices a product the URL shows, a URL redirect test starts or lands on the page, a read on this client returned a test’s data, getClientState() was read, or the request is a preview session. A shared cache must then not keep one copy of the page for everyone.
isTesting
Server only, on a client made from a request. Returnstrue while any test runs for your store, whatever the page, and in a preview session.
getSetCookieHeaders
Server only. Returns theSet-Cookie values the SDK needs on the response, only for cookies that changed, such as on a first visit. [] in the browser and on a client made with pageKey. On Next.js, the middleware sets them for you.
refreshTests
Server only. Fetches a fresh copy of your tests on this server now. If the fetch fails, the old copy is kept. See How the copy refreshes.track
Browser only. Records a storefront event for the visitor. Does nothing on the server. See Page views and add to cart.string
required
'page_viewed', 'product_viewed', 'product_added_to_cart', or the name of a custom event in ABConvert.object
{ productId, variantId } for product_viewed, { variantId, quantity } for product_added_to_cart, none for page_viewed.trackExposure
Browser only. Records that the visitor experienced a test, once per test per visit. Call it once a test price or an offer is on screen. See Exposure.string | number
required
price.experimentId or offer.experimentId from the object you rendered.setConsent
Browser only. Updates the visitor’s answer to your cookie banner. What the SDK held is sent whenanalytics becomes true, and dropped when it becomes false. See Consent.
{ analytics: boolean }
required
Browser client
hydrateABConvert
Builds the browser client from what the server handed over, without React.ABConvertProvider does this for you. See Other stacks.
Signature
ClientState | PageState | null
required
getClientState() or getPageState() from the server, as the page carried it.HydrateOptions
void
Begins tracking: reports what is pending once consent allows. Call it once the page has loaded. Calling it again does nothing.
void
Stops waiting for the visitor’s consent. What is held stays held.
() => void
Calls
listener after a forced test group changes what the reads return. Returns the function that removes the listener.React
From@abconvert/headless/react. On Hydrogen, import both from the Hydrogen entry instead.
ABConvertProvider
Shares the client with every component under it and records which test groups the visitor saw. Pass exactly one ofstate, pageState, or options. A server component can render it directly.
ClientState
getClientState() from your server: a page rendered for its visitor.PageState
getPageState() from your server: a page rendered for its test groups, which a cache may serve to everyone in them. The provider reads the visitor from their cookies once it mounts.ABConvertOptions
Browser-only mode, with no server: the
createABConvert options without request. The tests load after the page does, and isReady is false until then. See Browser only.(assignment: Assignment) => void
Runs once for each test the visitor is in, on every page load, once the visitor allows analytics. Not for forced or preview assignments. See Send test groups to another tool.
boolean
default:"false"
Hold all tracking until Shopify’s Customer Privacy API loads and allows analytics. See Consent.
useABConvert
Returns the client for the nearest provider: every method, plusisReady.
boolean
false only in browser-only mode, until the tests load and the visitor is assigned. Hide prices until it is true.Next.js
From@abconvert/headless/next. See the Next.js guide and Next.js caching and CDN.
abconvertMiddleware
Sets the SDK’s cookies, passes the visitor on to your pages, redirects for a URL redirect test, rewrites a tested page to its page key, and setscache-control where a shared cache must not keep the response. Returns the response for Next.js to send. Call it from your middleware or proxy function.
Signature
NextRequest
required
NextOptions
required
The
createABConvert options except request and pageKey, plus:planMiddleware
WhatabconvertMiddleware would do with the request, as data, for a middleware of your own that also rewrites. Apply every field to your response, as the sample does. Resolves to null for a request that is not a page, such as an image.
Signature
abconvertMiddleware. The plan has these fields:
string
The absolute URL to redirect to. Absent when the visitor stays.
307 | 308
307 for a URL redirect test, 308 for a direct visit to the rewrite prefix. Present with redirect.string
The page key path to render instead,
/<prefix>/<page key><path><query>. Present when a test changes the page, and on a server action from such a page.string
The page key,
'' when no test changes the page. Absent on a redirect, on a request left alone, and on a server action from a page no test changes.Headers
The request headers to render the page with. Absent on a redirect. For a server action, they keep the action on the same copy of your tests as the page the visitor saw.
string[]
Set-Cookie values to append to the response.Record<string, string>
Headers to set on the response, such as
cache-control: private.createABConvert on Next.js
The client a layout, page, or server action renders with. Never sets cookies; the middleware does.Signature
NextOptions
required
The
createABConvert options except request. With pageKey, the client for a cached page: it reads no request, so the page stays static. Without it, the client for the request the middleware prepared, which makes the page dynamic; use it in a server action or route handler.Hydrogen
From@abconvert/headless/hydrogen on 2026.10 and later, or @abconvert/headless/hydrogen/analytics-provider before 2026.10. See the Hydrogen guide.
createABConvert on Hydrogen
The server client for a loader. The same ascreateABConvert with request, except that it tracks nothing until Shopify’s Customer Privacy API wrote the visitor’s answer, and sets a cookie only when one changed, so a route that renders no test’s data carries no Set-Cookie and can stay in the full-page cache. Exported by both Hydrogen entries.
Signature
ABConvertOptions
required
The
createABConvert options. request is required; expectCustomerPrivacy is set for you.ABConvertProvider on Hydrogen
The React provider, which also listens to Hydrogen’s analytics for page views, product views, and add to cart, and waits for the visitor’s consent. On 2026.10 and later, render it below Hydrogen’sShopifyScripts; before 2026.10, inside Analytics.Provider. Takes the provider’s props except expectCustomerPrivacy, which is always on.
keepPrivateWhenTested
Turns apublic Cache-Control or Oxygen-Cache-Control header into private when a test can change the route, when the response sets a cookie, or when the client could not load your tests. Call it on the response headers of a route that opts into Oxygen’s full-page cache, after the loader’s reads. Returns true when it changed a header. See Hydrogen full-page cache.
Signature
Headers
required
Your route’s response headers, with its cache setting already on them.
ServerABConvert
required
The client from
createABConvert for this request.ABConvertCartAttributes
Writes ABConvert’s cart attributes to the cart whenever it lacks one or holds an older value, and keeps the cart’s other attributes. It waits until no cart change is in flight. When an update fails, it tries again after 1, 2, 4… seconds, up to 30. Render it once, inside bothCartProvider and ABConvertProvider. Exported by @abconvert/headless/hydrogen only, for 2026.10 and later, where the cart changes in the browser. See Write the cart attributes.
Signature
UseCart
required
The
useCart hook that createCartComponents returns in your app.useCartReadyForCheckout
Returnstrue once the cart carries ABConvert’s current attributes. Checkout charges what they say, so hold your checkout button until then. Exported by @abconvert/headless/hydrogen only, for 2026.10 and later.
Signature
UseCart
required
The
useCart hook that createCartComponents returns in your app.Objects
Assignment, TestGroup, Price, ShippingRate, FreeShippingThreshold, and Offer are the same objects as on the JavaScript API, described under its Objects. The headless SDK adds these.
Feature test fields
For a feature test, coming soon:string
The feature key set on the test. Absent for every other test type.
Record<string, string | number | boolean>
The values set for that test group.
{} for every other test type.CartAttribute
string
string
CheckoutLine
string | number
The product variant ID.
number
ClientState
WhatgetClientState() hands the browser: the visitor, their test groups, and the tests cut to what they see. It identifies the visitor, so a page that carries it is that visitor’s alone. Pass it to the provider’s state or to hydrateABConvert as it is.
PageState
WhatgetPageState() hands the browser. It holds nothing about the visitor, so a cached page can carry it. Pass it to the provider’s pageState or to hydrateABConvert as it is.
string
The key the page was rendered for.
'' when no test changes the page.string
The country the page was priced for.
Assignment[]
The key’s test groups: what the page renders for.
TypeScript
Every type on this page is exported. The options areABConvertOptions, and NextOptions and MiddlewarePlan from @abconvert/headless/next. UseCart, from @abconvert/headless/hydrogen, is the type of the useCart argument. createABConvert returns an ABConvert: a ServerABConvert when made from a request, a PageABConvert when made with pageKey, and hydrateABConvert returns a BrowserABConvert. The objects are Assignment, TestGroup, Price, ShippingRate, FreeShippingThreshold, Offer, CartAttribute, CheckoutLine, ClientState, and PageState.