Overview

The @flagsync/js-sdk integrates into web applications for client-side feature management and event tracking—ideal for single-user contexts like browser environments.

Installation

Install the SDK with your preferred package manager:

npm install @flagsync/js-sdk

Quickstart

A basic example of using the SDK in a JavaScript application:

import { FlagSyncFactory } from '@flagsync/js-sdk';


// Initialize the SDK

const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: {

    key: 'user-123', // Unique identifier

    attributes: {

      plan: 'premium',

      country: 'US'

    }

  }

});


// Get the client

const client = factory.client()


// Wait for SDK to be ready

await client.waitForReady();


// Evaluate a flag

const isFeatureEnabled = client.flag('my-feature-flag');

Initialization

Get Your SDK Key

Find your client-side SDK key in your workspace settings—safe for web/mobile apps (keep server-side keys private).

Initialize the SDK

Initialize the SDK with your SDK key and a user context (e.g., user ID):

import { FlagSyncFactory } from '@flagsync/js-sdk';


const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: {

    key: 'user123', // Unique identifier

    attributes: {

      email: 'user@example.com'

    }

  }

});


const client = factory.client();

Ensure the key in FsUserContext is unique and persistent for accurate MAU tracking and consistent flag evaluations. See User Context Best Practices for details.

Wait for Readiness

Use events or promises to ensure the SDK is ready before evaluating flags:

1

Promises

await client.waitForReady();

// SDK is ready
2

Events

import { FsEvent } from '@flagsync/js-sdk';


client.once(FsEvent.SDK_READY, () => {

  // SDK is ready

});

This event only fires when using the localstorage storage type; the default is memory.

Usage

Evaluate Flags

Evaluate flags with flag(), which applies targeting rules, rollouts, and defaults for the user context.

client.flag<T>(flagKey: string, defaultValue?: T);

An Impression is automatically registered when flag() is called.

SDK Not Ready

If the SDK isn’t ready, it returns the defaultValue or control:

// SDK not ready

const one = client.flag('flag-one', false); // false (defaultValue)

const two = client.flag('flag-two');        // "control"

SDK Ready

Once ready, flag() returns the server-evaluated value:

await client.waitForReady();

const value = client.flag('flag-one'); // Server-evaluated value
  • Client-side SDKs can bootstrap via LocalStorage or an initial flag set—values apply until the SDK is ready.
  • See Flag Evaluation: Overview.

Track Events

Submit user actions with track()—use eventValue for numeric data or properties for rich context:

client.track(

  eventKey: string,

  eventValue?: number | null,

  properties?: Record<string, any> | null

);

There are two types of events:

client.track('page-load-time', 1.42);

Create metrics like “Average Purchase Price” from events—see Metrics Overview.

SDK Event Listeners

The SDK emits these events for SDK lifecycle management:

  • SDK_UPDATE: Emitted when flags are updated
  • SDK_READY: Emitted when the SDK is ready
  • SDK_READY_FROM_STORE: Emitted when flags are loaded from storage
  • ERROR: Emitted when an error occurs during initialization
import { FsEvent } from '@flagsync/js-sdk';


// Flag updates

client.on(FsEvent.SDK_UPDATE, () => {

  console.log(`Flags updated at ${new Date().toISOString()}`)

});

SDK_UPDATE does not fire if syncing is disabled.

Error Handling

import { FsServiceError } from '@flagsync/js-sdk';


// Via events

client.on(FsEvent.ERROR, (error: FsServiceError) => {

  console.error('SDK Error:', error);

});


// Via promises

try {

  await client.waitForReadyCanThrow();

} catch (error) {

  console.error('Initialization Error:', error as FsServiceError);

}

All exposed errors are normalized to FsServiceError.

Configuration

Configure the SDK with the FsConfig interface:

interface FsConfig {

  sdkKey: string;                     // Required: Your SDK key

  core: {

    key: string;                      // Required: User identifier

    attributes?: Record<string, any>; // Optional: Custom user attributes

  };

  bootstrap?: Record<string, any>;    // Optional: Initial flag values

  storage?: {

    type?: 'memory' | 'localstorage'; // Optional: Storage type

    prefix?: string;                  // Optional: Storage key prefix

  };

  sync?: {

    type?: 'stream' | 'poll' | 'off'; // Optional: Sync strategy

    pollRate?: number;                // Optional: Polling interval in seconds

  };

  tracking?: {

    impressions?: {

      maxQueueSize: number;           // Required: Max impressions queue size

      pushRate: number;               // Required: Impressions push rate

    };

    events?: {

      maxQueueSize: number;           // Required: Max events queue size

      pushRate: number;               // Required: Events push rate

    };

  };

  urls?: {

    sdk?: string;                     // Optional: SDK endpoint URL

  };

  logger?: Partial<ILogger>;          // Optional: Custom logger

  logLevel?: LogLevel;                // Optional: Logging level

  metadata?: Record<string, any>;     // Optional: Additional metadata

}

Custom Attributes

Define user attributes for targeting in Flags: User Segments.

const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: {

    key: 'user-123',

    attributes: {

      plan: 'premium',

      country: 'US',

      userType: 'enterprise'

    }

  }

});

Ensure the key in FsUserContext is unique and persistent for accurate MAU tracking and consistent flag evaluations. See User Context Best Practices for details.

Flag Syncing

Configure flag update strategies with the sync object: stream, poll, or off.

By default, flag updates propagate in milliseconds via server-side events (SSE), ensuring the latest values are used in evaluations.

1

Stream (Default)

Stream updates via SSE—flag updates are reevaluated on the server and sent to the client:

const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: { key: 'user-123' },

  sync: {

    type: 'stream'

  }

});
2

Polling

Poll the server on an interval:

const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: { key: 'user-123' },

  sync: {

    type: 'poll',

    pollRate: 60

  }

});
3

Off

Disable syncing:

const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: { key: 'user-123' },

  sync: {

    type: 'off'

  }

});

Bootstrapping

Initialize the SDK with a set of bootstrap flags:

const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: { key: 'user-123' },

  bootstrap: {

    'my-feature-flag': true,

    'another-flag': 'value'

  }

});

Bootstrapped values apply before the SDK is ready—see Flag Evaluation: Overview.

Storage

Choose between memory and LocalStorage storage types:

1

Memory (Default)

const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: { key: 'user-123' },

  storage: {

    type: 'memory'

  }

});
2

LocalStorage

const factory = FlagSyncFactory({

  sdkKey: 'your-sdk-key',

  core: { key: 'user-123' },

  storage: {

  type: 'localstorage'

    prefix: 'flagsync' // Optional: Custom prefix for storage keys

  }

});
The SDK_READY_FROM_STORE event fires when loading from LocalStorage—no network request needed, but data may be stale.

Best Practices

  • Wait for SDK readiness before evaluating flags.
  • Select a sync strategy (stream/poll/off) based on your application’s needs.
  • Add user attributes for targeted feature rollouts.
  • Consider bootstrapping for faster initial renders.

Environment Variables

Set the following environment variable:

  • FLAGSYNC_SDK_KEY: Your client-side FlagSync SDK key (required)