JavaScript SDK (Browser)

Run experiments and feature flags on your website

Add It to Your Site

Drop this into your page. It defines window.abmeter:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/abmeter.iife.min.js"></script>

Then configure it with a publishable key - one that begins with pk_, minted on the API Keys page (available after signing in). It is safe to leave in page source: the server restricts it to the three endpoints this SDK uses. Secret keys (api-...) are rejected.

<script>
  abmeter.configure({ apiKey: 'pk_your_publishable_key' });

  abmeter.ready().then(() => {
    const color = abmeter.resolveParameter('checkout-button-color') ?? 'green';
    document.querySelector('#checkout').style.background = color;
  });

  document.querySelector('#checkout').addEventListener('click', () => {
    abmeter.trackEvent('purchase');
  });
</script>

That is a complete integration. The ?? 'green' fallback is what renders when no experiment is running, so the page is correct before you create anything in ABMeter.

Using a Bundler

With Vite, webpack, Next.js, or any other build step, install from npm instead of the CDN:

npm install abmeter
import * as abmeter from 'abmeter';

Everything above works the same way. ESM and CommonJS both resolve, and TypeScript types ship with the package - there is no separate @types install.

Before You Go to Production

Pin the exact version. The URL above is a range - @0.3 takes patch releases automatically, which is convenient while you are building and still means a release you did not deploy can reach your site. An exact version cannot change under you:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/abmeter.iife.min.js"></script>

Dropping the version entirely - npm/abmeter/dist/... - is the one form to avoid: it follows every release, including the breaking ones.

unpkg serves the same file at the same path if you prefer it.

Core Concepts

Parameters represent feature variations - a parameter has a set of possible values assigned to users through experiments or feature flags. Use resolveParameter to read the value for the current visitor.

Events are user actions you want to measure - page views, purchases, clicks. Track them with trackEvent to analyze how parameter variations affect behavior.

Users are identified by a userId - the randomization unit. Anonymous visitors get one generated for them, remembered across visits, so a returning visitor keeps seeing the same variation. Pick one id per visitor and stay with it: switching mid-experiment, such as across the login boundary, re-randomizes them.

Reading Values

await abmeter.ready();

const buttonColor = abmeter.resolveParameter('checkout-button-color');
// => 'blue' (the assigned variant's value for this visitor)

Returns undefined for a parameter no experiment or feature flag controls. The call makes no network request - it reads a value already fetched - and records that this visitor saw it.

Tracking Events

abmeter.trackEvent('purchase');

To attach data your metrics can read, pass it second:

abmeter.trackEvent('purchase', { price: 49.99, currency: 'USD' });

There is no user-id argument, unlike the server-side SDKs. The event belongs to whoever configure established, which on a page is the only person there is.

Nothing is sent right away: events are batched and submitted in the background, including when the visitor closes the tab. Call abmeter.flush() on single-page-app route changes if you want them sent sooner.

Content blockers may drop telemetry at the network layer. The SDK treats that as expected loss and never throws.

API

Function Description
configure(options) Initialize the SDK. apiKey is required; baseUrl, user, flushInterval, logger, and errorCallback are optional.
ready() Resolves once the first assignment fetch has completed.
resolveParameter(slug) The value assigned to this visitor, or undefined. Queues an exposure lazily.
trackEvent(slug, fields?) Queue an event for the configured user.
flush() Drain the queue now. Returns a promise.
reset(options?) Drain fully and tear down timers and listeners. Call configure again to restart.

Every read and track function is error-safe: failures are logged, passed to errorCallback when you supply one, and return a safe default rather than throwing.

Where Assignments Come From

Worth knowing if you also use the Ruby or Python SDK, or are wondering what the SDK is doing on the network.

Those server-side SDKs download the assignment configuration and compute assignments locally. A browser cannot do that safely: shipping assignment rules, salts, and audience definitions to the client would expose every experiment you are running and let anyone holding the key forge assignments for arbitrary user ids.

So this SDK asks ABMeter for pre-evaluated assignments for the current visitor and caches the resulting value map in localStorage. One request per visitor per session, refreshed in the background. Everything after that is local: resolving a parameter is a map lookup, and the browser never holds enough information to work out anyone else's assignment.

Next Steps