JavaScript API Reference

Overview

The Explore JavaScript API is available inside every experiment's variation code through two globals:

  • api - the per-experiment object.

  • _mktz - the site-wide Explore object, available everywhere.

Together they let you register variation logic, fire conversion goals, track interactions, read visitor data, and coordinate between experiments.

The experiment wrapper

Every variation script follows this IIFE pattern:

(function (_mktz, api) {
'use strict';

api.runnable(run);

function run() {
// variation logic + tracking go here
}
})(_mktz, _mktz._api.get('v0', '{MKTZ[EXP_ID]}'));
Note

{MKTZ[EXP_ID]} is a template token Explore replaces with the live experiment ID when the script is served. Hard-coding an ID also works, but the token keeps code portable across variations.

The api object

api.runnable(fn) - register your variation

Warning

Works in global.js only. Calling api.runnable in a variation file does nothing. In variation files, apply your DOM changes directly - don't register another runnable.

Pass the function that applies your changes. Explore calls it once the experiment is cleared to run (correct page, audience, and bucket).

api.isControl - detect the control group

A boolean, true when the visitor is in the control (original) variation. Use it to fire control-side tracking without touching the page:

function run() {
if (api.isControl) {
_mktz.push(['_Goal', 'ab-test-control-view', '1']);
return;
}
// variation changes…
}

api.goal(name, value?) - fire a conversion goal

Records a goal for the experiment. The optional second argument attaches a numeric or string value.

api.goal('clicked-product');
api.goal('click-filter', selectedFilter);

api.track(selector, options) - bind a goal to a DOM event

Declaratively attaches a goal to a DOM event without writing addEventListener manually.

api.track('.compare-tab input[type="radio"]', {
on: 'change',
name: 'click-card-selector',
value: ($element) => $element[0].defaultValue,
before: function (options, event, $element) {
if (event.isTriggered) return false;
},
});

Options:

Option

Type

Purpose

on

string

DOM event to listen for ('click', 'change', …)

name

string

Goal name

value

value or ($element) => …

Optional value; a function is evaluated at fire time

before

(options, event, $element)

Guard run before firing; return false to cancel

Warning

api.track only binds to elements already in the DOM. It resolves the selector and attaches its listener once, at call time - it does not use event delegation, so it won't fire for elements added later (lazy-loaded content, modals, AJAX, SPA route changes). For dynamic elements, either call api.track again after the element exists, or wire the goal manually by listening on a stable ancestor and calling api.goal() or _mktz.push(['_Goal', ...]) when the event matches.

api.storage - share state between experiment files

A free-form object scoped to the experiment, used to pass state or functions between global.js and variation files.

// global.js
api.storage.benefitsData = [...];
api.storage.fillBenefits = function () { /* … */ };

// variation-1.js (same experiment)
api.storage.fillBenefits();

Firing goals without the api object

When you only have _mktz available - shared snippets, code outside the experiment wrapper - push a goal onto the Explore queue directly:

_mktz.push(['_Goal', 'click-add-to-cart']);
_mktz.push(['_Goal', 'add-to-cart-pdp', value]);

This is equivalent to calling api.goal(name, value?).

The _mktz global

Events

_mktz.events.on('omni:changed:{MKTZ[EXP_ID]}', handler); // subscribe
_mktz.events.trigger('job_event', payload); // publish
_mktz.events.onceIdle(fn); // fires once the page goes idle
_mktz.events.onScroll(fn); // fires on scroll
_mktz.events.onExit(fn); // exit-intent (repeating)
_mktz.events.onceExit(fn); // exit-intent (fires once)

Cookies

_mktz._set_cookie('MY_KEY', '1', 10, '/');  // name, value, lifetime in hours, pathname 
var val = _mktz._get_cookie('MY_KEY'); // returns the value, or null

Visitor & session data - _mktz.visitor.*

Read-only properties about the current visitor: device_type, browser_name, browser_version, os, country, city, ip, session_id, uid, new_visitor, is_returning, visits_count, views_session, time_onsite, referer_type, history, resolution, landing_page.

if (_mktz.visitor.device_type === 'mobile') { /* … */ }
if (_mktz.visitor.new_visitor) { /* … */ }

Timing & promises

_mktz.promised.idle();       // resolves when the page is idle
_mktz.promised.delay(2); // resolves after N seconds

// Self-cleaning timers grouped by a tag
_mktz.taggedTimeouts.setTaggedInterval(fn, intervalMs, 'my-timer');
_mktz.taggedTimeouts.setTaggedTimeout(fn, delayMs, 'my-timer');
_mktz.taggedTimeouts.clearTaggedTimers('my-timer');

Checking other active experiments

// Find a specific running experiment
_mktz.running_test.find((exp) => Number(exp.id_experiment) === 54628);

// Check if another experiment is active
_mktz.running_test.some((exp) => exp.id_experiment === 1290320);

// Read config for the current experiment
var cfg = _mktz.experiments['{MKTZ[EXP_ID]}'] || {};

// Variations the visitor has already been exposed to
_mktz.getSeenVariations(); // e.g. ['1321240=1', ...]

Other utilities

_mktz.validator.validateEmail(value);                          // boolean
_mktz._get_parameter('utm_campaign', window.location.href); // query param, or false
_mktz.applyExperiment('50015-116135'); // force-apply experiment-variation
_mktz.id_website; // the Explore site ID
_mktz.Promise.all([p1, p2]).then(/* … */); // bundled Promise

Template tokens

Token

Replaced with

{MKTZ[EXP_ID]}

The experiment ID at serve time

Always use the token instead of hard-coding IDs, so the same code stays portable across variations.

Full example

(function (_mktz, api) {
'use strict';

api.runnable(run);

function run() {
// Control group: measure the original without changing it
if (api.isControl) {
api.goal('control-view');
return;
}

// Variation: apply DOM changes
var checkoutBtn = document.querySelector('#CartPage .checkout-btn');
if (checkoutBtn) {
checkoutBtn.textContent = 'Buy now';
}

// Track clicks on the button
api.track('#CartPage .checkout-btn', {
on: 'click',
name: 'click-checkout',
value: function ($el) { return $el.text().trim(); },
});
}
})(_mktz, _mktz._api.get('v0', '{MKTZ[EXP_ID]}'));

Quick reference

Call

Context

Purpose

_mktz._api.get('v0', id)

wrapper

Returns the experiment api object

api.runnable(fn)

global.js only

Register the variation entry point

api.isControl

anywhere

true for the control bucket

api.goal(name, value?)

anywhere

Fire a conversion goal

api.track(selector, opts)

anywhere

Bind a goal to a DOM event

api.storage

anywhere

Share state between experiment files

_mktz.push(['_Goal', name, value?])

anywhere

Fire a goal without the api object

_mktz.events.on/trigger/once*

anywhere

Pub/sub + page lifecycle events

_mktz._set_cookie / _get_cookie

anywhere

Read/write cookies

_mktz.visitor.*

anywhere

Visitor & session data

_mktz._is_preview()

anywhere

Detect the Explore editor/preview

_mktz.running_test / _mktz.experiments

anywhere

Other experiments active for the visitor


Updated