Skip to main content
The Web SDK is currently in alpha. APIs and behavior may change between releases.
Who is this for? Web developers adding analytics to game websites, landing pages, or web apps. Works with any framework (React, Next.js, Svelte, vanilla JS).
The Immutable Web SDK is a typed package for tracking player behavior on websites and web games. Session lifecycle (session_start, session_end) and attribution (UTM parameters, click IDs, referrer) are handled automatically. Page views are tracked by calling page() on each route change, and in-game moments like progressions, purchases, and sign-ups are triggered by your code when they happen.

What You Need

Installation

npm install @imtbl/audience

Quick Start

1

Initialize the SDK

import { Audience, AudienceEvents, IdentityType } from '@imtbl/audience';

const audience = Audience.init({
  publishableKey: 'YOUR_PUBLISHABLE_KEY',
});
Consent defaults to 'none' — the SDK won’t track anything until you explicitly set a consent level.
2

Set consent

The SDK uses a three-tier consent model ('none', 'anonymous', 'full'). Call setConsent after the user accepts your cookie banner or privacy prompt.
// User accepts anonymous tracking
audience.setConsent('anonymous');

// User logs in and accepts full tracking
audience.setConsent('full');
At 'anonymous', page views and events are tracked but identify() and alias() calls are dropped. At 'full', all methods are available. See the Data Dictionary for what is collected at each level.
3

Track page views

Call page() on each route change. The first call in each session includes attribution parameters.
audience.page();
4

Track events

Log player actions with track(). The SDK ships with predefined events for common player actions (purchases, sign-ups, progression, wishlist actions, and more) that give you typed properties and autocomplete. You can also pass any custom event string.
// Predefined event — typed properties
audience.track(AudienceEvents.SIGN_UP, { method: 'email' });
audience.track(AudienceEvents.PURCHASE, { currency: 'USD', value: 9.99 });

// Custom event — any properties
audience.track('tutorial_complete', { stepCount: 5 });
5

Identify users

Links anonymous activity back to a known player. Call when a player logs in or connects an account like Steam or Google. Requires 'full' consent.
audience.identify('player-123', IdentityType.Passport, {
  email: 'user@example.com',
});
6

Clean up on exit

Flushes the queue and sends a session_end event (if consent is above 'none').
audience.shutdown();

Complete Example

import { Audience, AudienceEvents, IdentityType } from '@imtbl/audience';

// 1. Initialize
const audience = Audience.init({
  publishableKey: 'YOUR_PUBLISHABLE_KEY',
});

// 2. Set consent after cookie banner
audience.setConsent('anonymous');

// 3. Track page views on route changes
audience.page();

// 4. Track player actions
audience.track(AudienceEvents.PURCHASE, { currency: 'USD', value: 9.99 });

// 5. Identify after login (requires 'full' consent)
audience.setConsent('full');
audience.identify('player-123', IdentityType.Passport, { email: 'user@example.com' });

// 6. Clean up on exit
audience.shutdown();

Verify the Integration

Initialize with debug: true to see SDK activity in the browser console:
const audience = Audience.init({
  publishableKey: 'YOUR_PUBLISHABLE_KEY',
  debug: true,
});
  1. Console: Look for log entries showing session_start, page, and any track() calls
  2. Network tab: Look for POST requests to https://api.immutable.com (or https://api.sandbox.immutable.com if you’re using a test key) — events flush every 5 seconds or when 20 events accumulate
Remove debug: true before deploying to production.

API Reference

Creates and returns an Audience instance. Call once when your app loads to set up tracking.
ParameterTypeRequiredDefaultDescription
publishableKeystringYesAPI key from Hub (starts with pk_imapik-)
consent'none' | 'anonymous' | 'full'No'none'Initial consent level
debugbooleanNofalseLog SDK activity to the browser console
cookieDomainstringNoCurrent domainShare cookies across subdomains (e.g. '.studio.com'). The Tracking Pixel uses domain for this same setting.
flushIntervalnumberNo5000How often the queue flushes, in milliseconds
flushSizenumberNo20Number of queued messages that triggers a flush
const audience = Audience.init({
  publishableKey: 'YOUR_PUBLISHABLE_KEY',
  consent: 'none',
  debug: true,
  cookieDomain: '.studio.com',
});
Controls what the SDK is allowed to collect. Call when the user accepts or changes their cookie preferences — takes effect immediately, no page reload needed. See the Data Dictionary for what each level enables.
Records a page view. Call on every route change to track which pages players visit and in what order. The first call in each session includes attribution parameters (UTMs, click IDs, referrer).
ParameterTypeDescription
propertiesRecord<string, unknown>Optional custom properties
Requires: 'anonymous' or 'full' consent. Calls at 'none' are silently dropped.
Records a player action. Call when a player does something you want to measure — a purchase, sign-up, level completion, or any custom action. Predefined events give you typed properties with autocomplete.
ParameterTypeDescription
eventstringAn AudienceEvents value (e.g. AudienceEvents.PURCHASE) or any custom string
propertiesRecord<string, unknown>Event properties. Required for predefined events that have required fields (e.g. purchase), optional otherwise.
Requires: 'anonymous' or 'full' consent. Calls at 'none' are silently dropped.
// Predefined event — typed properties
audience.track(AudienceEvents.PURCHASE, { currency: 'USD', value: 9.99, itemName: 'Sword' });

// Custom event — any properties
audience.track('tutorial_complete', { stepCount: 5 });
Links anonymous activity back to a known player. Call when a player logs in or connects an account like Steam or Google.
ParameterTypeDescription
idstringThe player’s identifier in that provider
identityTypeIdentityTypeWhich provider the ID comes from (see table below)
traitsobjectOptional — email, name, or custom key-value pairs
Requires: 'full' consent.
audience.identify('player-456', IdentityType.Passport, {
  email: 'user@example.com',
});
Identity types:
ValueProvider
'passport'Immutable Passport
'steam'Steam
'epic'Epic Games
'google'Google
'apple'Apple
'discord'Discord
'email'Email address
'custom'Custom identity system
You can also call identify(traits) with traits only to attach extra info (like an email) to the anonymous visitor without identifying them as a specific player. Also requires 'full' consent.
ParameterTypeDescription
traitsobjectemail, name, or custom key-value pairs
audience.identify({ email: 'user@example.com' });
Connects two accounts that belong to the same player. Call when a player links a second account (e.g. signs up with email, later connects Steam).
ParameterTypeDescription
from{ id: string, identityType: IdentityType }The account being linked
to{ id: string, identityType: IdentityType }The player’s main account
Requires: 'full' consent.
audience.alias(
  { id: 'steam-user-789', identityType: IdentityType.Steam },
  { id: 'player-456', identityType: IdentityType.Passport },
);
Wipes the current player’s identity and starts a fresh anonymous session. Call when a player logs out so the next player on the same device isn’t mixed up.
audience.reset();
Sends all queued events to the server immediately. Call when you need events delivered right now instead of waiting for the next automatic flush. Returns a Promise that resolves when the batch is sent.
await audience.flush();
Sends any remaining events and shuts down the SDK. Call when the app unmounts or the page is about to unload. Fires a session_end event if consent is above 'none'.

Next Steps

Data Dictionary

Full reference of collected data at each consent level

Tracking Pixel

No-code snippet for marketing sites

Attribution

Learn how tracking data powers player attribution

API Keys

Manage your publishable and secret keys