JS-API test workflow

Create a JavaScript API test in the app, copy the hypothesis id, and gate your variant render on await window.abtest.isHypothesisActive(id).

A JavaScript API test is the type where you render the variants in code. The app buckets each visitor and exposes the assignment through window.abtest; your theme or script decides what to draw. This page walks the full loop, from creating the test to reading its results.

JavaScript API tests are available on the Premium plan and above. See plans. For the other three test types (URL, template, theme) the app performs the delivery for you and no code is needed.

Before you begin

Step 1: Create the JavaScript API test

  1. In the AB Test admin, create a new experiment and choose the JavaScript API type.
  2. Define your variants: a control (variant A) and one hypothesis (variant B). These are logical buckets — the app does not render them; your code does.
  3. Choose a trigger: automatic or manual. This decides when a visitor is counted as entering the test. See Automatic vs manual trigger below.
  4. Optionally add audience targeting rules (device, new vs returning, country, UTM, referrer, cookie) and a schedule. The test auto-ends at its end date.
  5. Save and start the test.

Automatic vs manual trigger

Both triggers bucket the visitor the same way. The difference is the moment the visitor is enrolled — the moment they count toward the test's data.

TriggerEnrols the visitor when…Use it when…
Automatic the assignment loads on page view — before your code runs. the variant affects the page for essentially every visitor who loads it (for example, a headline or layout that always renders).
Manual your code first calls isHypothesisActive() and reaches that assignment. the variant only appears in a specific place or after an interaction (a step in a flow, a modal, below the fold), so only visitors who actually reach it should count.

Manual triggers keep your results clean. If only 30% of visitors ever reach the code path that renders variant B, enrolling all 100% would dilute the measured effect. With a manual trigger, the first isHypothesisActive() call enrols the visitor at that exact point — no extra call is required from you.

Step 2: Copy the hypothesis id

Each variant has a stable id. From the test's setup screen, copy the id of the hypothesis (variant B) — this is the value you pass to isHypothesisActive(). It is safe to hard-code; it does not change for the life of the test.

The id you pass identifies which variant to check. isHypothesisActive(id) resolves true only when the visitor is assigned to that variant, so gate your variant-B rendering on the variant-B id.

Step 3: Render the variant in your code

window.abtest.isHypothesisActive(id) returns a Promise that resolves to a boolean once assignments are known. Always await it (or use .then()). It fails open: on any error it resolves false, so the visitor sees the control experience.

<!-- Add this where the AB Test app embed has already loaded, e.g. near the
     end of the template or in a snippet that renders the affected area. -->
<script>
  (async function () {
    // The hypothesis (variant B) id you copied from the test's setup screen.
    var HYPOTHESIS_ID = "var_2f8c1a9b";

    // window.abtest is provided by the AB Test app embed. Guard in case this
    // block runs before the embed script has defined it.
    if (!window.abtest) return;

    // Resolves true only for visitors bucketed into this variant. For a
    // manual-trigger test, this first call also enrols the visitor.
    if (await window.abtest.isHypothesisActive(HYPOTHESIS_ID)) {
      renderVariantB();
    }
    // Control visitors fall through and keep the existing (variant A) experience.
  })();

  function renderVariantB() {
    var cta = document.querySelector("[data-hero-cta]");
    if (cta) cta.textContent = "Start your 15-day trial";
  }
</script>

Ordering matters. The app embed defines window.abtest when its script loads; your block must run after that. The if (!window.abtest) return; guard prevents an error if it hasn't loaded yet — place your script so it evaluates after the embed, or defer it (for example on DOMContentLoaded).

Reading the raw assignment (optional)

window.abtest.getVisitorData() returns the current visitor id and known assignments synchronously. Because it does not wait, it may be empty before assignments load, and it does not enrol a manual-trigger visitor. Use it for logging or debugging; use isHypothesisActive() for any decision that gates rendering.

var data = window.abtest.getVisitorData();
// { visitorId: "…", assignments: [ { experimentId: "…", variantId: "…" } ] }

Full method signatures live in the JavaScript API reference.

Step 4: Confirm the app embed is enabled

Without the app embed, window.abtest is undefined and no variant renders.

  1. Go to Online Store > Themes > Customize on your published theme.
  2. Open App embeds in the left panel.
  3. Toggle AB Test on and save.

Quick check in the browser console on your storefront: typeof window.abtest should return "object". If it returns "undefined", the embed is off or not on the published theme.

Step 5: Verify and read results

Before trusting live traffic, force yourself into the variant to confirm it renders. Append a preview parameter to any storefront URL:

https://your-store.example.com/?ab_preview=<experimentId>:<variantId>

A forced preview always resolves fresh (it bypasses the cached assignment) and is never recorded, so it will not pollute the test's data. Load the page with your hypothesis id and confirm variant B appears; drop the parameter and confirm control appears.

Once real traffic is flowing, open the experiment's results. You get Bayesian probability-to-be-best per variant, per-variant conversion rate and revenue, and segment breakdowns (device, new vs returning, country, UTM, referrer, cookie). Revenue is attributed even through third-party and Shop Pay checkouts via the visitor id stamped on the cart — see revenue attribution. When a winner is clear, you can apply it in one click.

New to A/B testing here? Start with the quickstart, then read JavaScript tests for a conceptual overview of this test type.