Browse docs

Explore by section, then jump directly into a page.

Browser SDK

Web SDK

Add Flash Analytics to any browser app, SPA, or script-tag integration with one import.

The Web SDK handles page views, link clicks, data-attribute events, JavaScript errors, session access, A/B experiment assignments, and remote config — all from a single@flash-analytics/web import.

Installation

1

Install the package

Terminal
npm install @flash-analytics/web@2.2.3
Terminal
pnpm add @flash-analytics/web@2.2.3
2

Initialize once at app startup

Create a shared analytics.ts module and import it everywhere you track events.

analytics.tsTypeScript
import { FlashAnalytics } from '@flash-analytics/web';

export const analytics = new FlashAnalytics({
  appId: process.env.FLASH_APP_ID!, // must be a UUID
  capturePageViews: true,
  captureExternalLinks: true,
  captureDataAttributes: true,
  captureErrors: true,
});

appId must be a UUID

The appId must be a valid UUID (e.g. 00000000-0000-4000-8000-000000000000). Placeholder strings will fail validation. Get your UUID from the Flash dashboard.
3

Identify users after login

TypeScript
await analytics.identify({
  profileId: 'user_123',
  email: 'user@example.com',
  properties: { plan: 'pro' },
});
4

Track events

TypeScript
analytics.track('checkout_started', {
  cartValue: 129.50,
  currency: 'USD',
  itemCount: 3,
});

Auto-capture

Enable capture flags at init time — the SDK wires up the listeners automatically.

capturePageViews

Fires on load and every history change

captureExternalLinks

Tracks outbound link clicks

captureDataAttributes

Clicks on fa-track annotated elements

captureErrors

Global errors and unhandled rejections

captureHashNavigation

Hash-only navigation changes

captureVariants

Experiment assignments on session start

Global properties

Call setGlobalProperties once and the SDK merges them into every subsequent event.

TypeScript
analytics.setGlobalProperties({
  appVersion: '1.2.0',
  plan: 'pro',
  environment: 'production',
});

Experiments

Enable captureVariants to automatically sync assignments on each new session and after identify().

TypeScript
// All cached assignments — no API call
const all = analytics.getAllExperiments();

// Single experiment — cache first, then API fallback
const assignment = await analytics.getExperimentById('checkout-cta');
console.log(assignment?.variantName); // 'variant_a' | 'control'

// Manual — always calls the API
const variant = await analytics.assignExperiment('checkout-cta');

Remote config

TypeScript
const config = await analytics.fetchRemoteConfig({
  country: 'US',
});

const enabled  = config.getBoolean('new_checkout', false);
const title    = config.getString('checkout_title', 'Checkout');
const maxItems = config.getNumber('max_cart_items', 50);

Session access

Browser sessions are restored during SDK initialization when a valid cached session exists. Use getSession() for a synchronous read, and onSessionUpdated when another part of your app needs the session as soon as the SDK restores, creates, or refreshes it.

TypeScript
const analytics = new FlashAnalytics({
  appId: 'YOUR_APP_ID',
  onSessionUpdated(session) {
    console.log(session.id);
    console.log(session.estimatedExpiresAt); // epoch milliseconds
    console.log(session.estimatedTtlMs);     // number
  },
});

const session = analytics.getSession();

console.log(session?.id);
console.log(session?.estimatedExpiresAt); // epoch milliseconds
console.log(session?.estimatedTtlMs);     // number

The callback can run during initialization if the Web SDK restores an unexpired session from sessionStorage or cookies. It also runs after a track(), identify(), or batch flush response returns session data.

Device ID is stored in cookies and localStorage. Session data uses sessionStorage and cookies so session restore works even if one storage mechanism is blocked.

Script tag (no bundler)

HTML
<script>
  window.fa = window.fa || function () {
    var q = [];
    return new Proxy(function () {
      arguments.length && q.push([].slice.call(arguments));
    }, {
      get: function (_t, key) {
        return key === 'q' ? q : function () {
          q.push([key].concat([].slice.call(arguments)));
        };
      }
    });
  }();

  window.fa('init', {
    appId: 'YOUR_APP_ID',
    capturePageViews: true,
    captureErrors: true,
  });
</script>
<script src="https://dashboard.flashanalytics.app/fa1.js" defer async></script>

Batching

Enable batching for high-volume apps to reduce network calls. Queued events keep their original event timestamp, and session responses from batch flushes still update getSession() and onSessionUpdated.

TypeScript
const analytics = new FlashAnalytics({
  appId: 'YOUR_APP_ID',
  deliveryStrategy: {
    strategy: 'batching',
    config: {
      size: 10,              // flush when 10 events queued
      timeout: 5000,         // or every 5 seconds
      fallbackToIndividual: true,
    },
  },
});

// Flush manually (e.g. before page unload)
await analytics.flushBatch();

Web batching also flushes with keepalive on page hide and when the page becomes hidden, so queued events are released during normal browser lifecycle changes.