The availability of features may depend on your plan type. Contact your Customer Success Manager if you have any questions.
Dev guideRecipesAPI ReferenceChangelog
Dev guideAPI ReferenceRecipesChangelogUser GuideGitHubDev CommunityOptimizely AcademySubmit a ticketLog In
Dev guide

Initialize the JavaScript SDK v6+

How to initialize the Optimizely Feature Experimentation JavaScript SDK versions 6 and above in your application.

Returns

Returns an instance of the Client interface or throws an error if an invalid configuration is passed.

Examples

To instantiate using an SDK key, obtain the SDK Key from your project's settings and pass it in.

  1. Go to Settings > Environments.
  2. Copy and save the SDK Key for your environment.
import {
  createBatchEventProcessor,
  createInstance,
  createOdpManager,
  createPollingProjectConfigManager,
} from "@optimizely/optimizely-sdk";

const SDK_KEY="YOUR_SDK_KEY";

const pollingConfigManager = createPollingProjectConfigManager({
  sdkKey: SDK_KEY,
  autoUpdate: true,
  updateInterval: 60000, // 1 minute
});

const batchEventProcessor = createBatchEventProcessor();
const odpManager = createOdpManager();

const optimizelyClient = createInstance({
  projectConfigManager: pollingConfigManager,
  eventProcessor: batchEventProcessor,
  odpManager: odpManager,
});

optimizelyClient
  .onReady().then(() => {
    console.log("Client is ready");
    // Do something
  }).catch((err) => {
    console.error("Error initializing Optimizely client:", err);
    // Handle error
  });
<script src="https://unpkg.com/@optimizely/optimizely-sdk/dist/optimizely.browser.umd.min.js"></script>
 <!--this adds the datafile on the window variable window.optimizelyDatafile!-->
<script src="https://cdn.optimizely.com/datafiles/<YOUR_SDK_KEY>.json/tag.js"></script>

<script>
    const {
      createPollingProjectConfigManager,
      createBatchEventProcessor,
      createOdpManager,
    } = window.optimizelySdk;
  
    const SDK_KEY="YOUR_SDK_KEY";

    const pollingConfigManager = createPollingProjectConfigManager({
      sdkKey: SDK_KEY,
      datafile: window.optimizelyDatafile,
      autoUpdate: true,
      updateInterval: 60000, // 1 minute
    });

    const batchEventProcessor = createBatchEventProcessor();
    const odpManager = createOdpManager();
  
    const optimizelyClient  = window.optimizelySdk.createInstance({
      projectConfigManager: pollingConfigManager,
      eventProcessor: batchEventProcessor,
      odpManager: odpManager,
    });
  
  	if (!optimizelyClient) {
  		// There was an error creating the Optimizely client
    } else {
      optimizelyClient
        .onReady()
        .then(() => {
          console.log("Client is ready");
          // Do something
        })
        .catch((err) => {
          console.error("Error initializing Optimizely client:", err);
          // Handle error
        });
    }
</script>

onReady method

onReady returns a promise that fulfills when this instance is ready to use (meaning it has a valid datafile), or rejects when it has failed to become ready within a period of time (configurable by the timeout property of the options argument), or when this instance is closed through the close method before it became ready.

If a static project config manager with a valid datafile was provided in the constructor, the returned Promise is immediately fulfilled. If a polling config manager was provided, it is used to fetch a datafile, and the returned promise will fulfil if that fetch succeeds, or it will reject if the datafile fetch does not complete before the timeout. The default timeout is 30 seconds.

The returned Promise is fulfilled with an unknown result which does not need to be inspected to know that the instance is ready. If the promise is fulfilled, it is guaranteed that the instance is ready to use. If the promise is rejected, it means the instance is not ready to use, and the reason for the promise rejection will be an error denoting the cause of failure.

Project config manager

The project config manager is responsible for managing the project configuration of an Optimizely client instance. It is a required component for creating a client instance. You can choose between the following two types of project config manager:

Poll project config manager

This regularly polls the configuration at a specified interval (default is five minutes).

import { createPollingProjectConfigManager, createInstance } from "@optimizely/optimizely-sdk";

const SDK_KEY = "YOUR_SDK_KEY"

const pollingConfigManager = createPollingProjectConfigManager({
  sdkKey: SDK_KEY,
  autoUpdate: true,
  updateInterval: 60000
});

const optimizelyClient = createInstance({
  projectConfigManager: pollingConfigManager
});

optimizelyClient
  .onReady().then(() => {
    console.log("Client is ready");
    // Do something
  }).catch((err) => {
    console.error("Error initializing Optimizely client:", err);
    // Handle error
  });

When you provide the sdkKey, the SDK instance asynchronously downloads the datafile associated with that sdkKey. When the download completes, the SDK instance updates itself to use the downloaded datafile. You can use the onReady promise method to wait for the datafile to download before using the instance.

See the following table to customize the behavior of the polling config manager using options of PollingConfigManagerConfig:

OptionTypeDescription
sdkKeystringThe key associated with an environment in the project.
datafile
optional
stringThe JSON string representing the project.
jsonSchemaValidator
optional
object

To perform JSON schema validation on datafiles.

Skipping validation enhances performance during initialization

autoUpdate
optional
booleanWhen true, and sdkKey was provided, automatic updates are enabled on this instance. The default value is false.
updateInterval
optional
numberWhen automatic updates are enabled, this controls the update interval. The unit is milliseconds. The minimum allowed value is 1000 (one second). The default value is 300000 milliseconds (five minutes).
urlTemplate
optional
stringA format string used to build the URL from which the SDK requests datafiles. Instances of %s are replaced with the sdkKey. When not provided, the SDK requests datafiles from the Optimizely CDN.
datafileAccessToken
optional
stringA bearer token used to authenticate requests when fetching the secure environment and needs authorization.
cache
optional
Store<string>An optional cache interface used to persist the downloaded datafile. This can be helpful to avoid unnecessary network requests.

Static project config manager

Uses the provided datafile and does not perform any network requests to fetch or update the configuration.

import { createInstance, createStaticProjectConfigManager } from "@optimizely/optimizely-sdk";

const SDK_KEY="YOUR_SDK_KEY";

const fetchDatafile = async () => {
  const response = await fetch(
    `https://cdn.optimizely.com/datafiles/${SDK_KEY}.json`
  );
  if (!response.ok) {
    throw new Error(`Failed to fetch datafile: ${response.statusText}`);
  }
  
  const datafile = await response.text();
  
  return datafile;
};

const datafile = await fetchDatafile();

const staticConfigManager = createStaticProjectConfigManager({
  datafile
})

const optimizelyClient = createInstance({
  projectConfigManager: staticConfigManager
});


optimizelyClient
  .onReady().then(() => {
    console.log("Client is ready");
    // Do something
  }).catch((err) => {
    console.error("Error initializing Optimizely client:", err);
    // Handle error
  });

To customize the behavior of the static config manager you can use the following options of StaticConfigManagerConfig:

OptionTypeDescription
datafilestringThe JSON string representing the project.
jsonSchemaValidator
optional
object

To perform JSON schema validation on datafiles.

Skipping validation enhances performance during initialization

Event processor

The event processor can be used to process decision event or conversion event. Optimizely provides two types of event processors.

Batch event processor

The batch event processor queues events and sends them in batches, improving performance by reducing network calls. You can configure the batch size, flush interval, and customize how events are dispatched or stored.

import {
  createInstance,
  createPollingProjectConfigManager,
  createBatchEventProcessor
} from "@optimizely/optimizely-sdk";

const batchEventProcessor = createBatchEventProcessor({
  batchSize: 5,
  flushInterval: 10000,
});

To customize the behavior of the batch event processor you can use the following options of BatchEventProcessorOptions:

OptionTypeDescription
eventDispatcher
optional
EventDispatcherA custom event dispatcher used to send events. If not provided, the default dispatcher is used.
closingEventDispatcher
optional
EventDispatcherA specialized custom dispatcher used to send any remaining events when the processor shuts down.
flushInterval
optional
numberThe time interval (in milliseconds) at which the event queue is automatically flushed. Default is 1000 milliseconds for browser and React Native and 30 seconds for NodeJS.
batchSize
optional
numberThe number of events to accumulate before sending them as a batch. Default is 10.
eventStore
optional
Store<string>A custom cache implementation to store events temporarily to track failed events to retry later on.

Forward event processor

The forwarding event processor sends events immediately using the provided event dispatcher, without batching or queuing. It is a simple, low-latency option ideal for scenarios where events need to be dispatched immediately. This is also a good choice if you want to employ your own logic to event processing, in which case you can use a custom event dispatcher with a forwarding event processor, which will just forward all events to your custom dispatcher.

import { createInstance, createForwardingEventProcessor } from "@optimizely/optimizely-sdk";

const SDK_KEY="YOUR_SDK_KEY";

const pollingConfigManager = createPollingProjectConfigManager({
  sdkKey: SDK_KEY,
});

const forwardingEventProcessor = createForwardingEventProcessor()

const optimizelyClient = createInstance({
  projectConfigManager: pollingConfigManager,
  eventProcessor: forwardingEventProcessor
});

To customize the behavior of the forwarding event processor you can use the following options:

OptionTypeDescription
eventDispatcher
optional
EventDispatcherA custom event dispatcher used to send events. If not provided, the default dispatcher is used.

OdpManager

OdpManager contains the logic supporting Real-Time Audiences for Feature Experimentation-related features, including audience segments, ODP events, and VUID tracking. You must configure this parameter to use Real-Time Audiences for Feature Experimentation.

To enable Real-time Audiences for Feature Experimentation you have to pass the OdpManager and configure Real-Time Audiences for Feature Experimentation.

import { createInstance, createOdpManager } from "@optimizely/optimizely-sdk";

const SDK_KEY="YOUR_SDK_KEY";

const pollingConfigManager = createPollingProjectConfigManager({
  sdkKey: SDK_KEY,
});

const odpManager = createOdpManager({
  eventApiTimeout: 1000,
  segmentsApiTimeout: 1000,
  segmentsCacheSize: 10,
  segmentsCacheTimeout: 1000,
  eventBatchSize: 5,
  eventFlushInterval: 3000,
});

const optimizelyClient = createInstance({
  projectConfigManager: pollingConfigManager,
  odpManager: odpManager
});

To customize the behavior of the OdpManager you can use the following options of OdpManagerOptions:

OptionTypeDescription
segmentsCache
optional
Cache<string[]>A custom cache implementation used to store fetched user segments locally. Helps avoid repeated API calls for the same user. If not provided, a default segments cache is used.
segmentsCacheSize
optional
numberThe maximum number of user segment entries to keep in the cache. Default is 1000.
segmentsCacheTimeout
optional
numberThe time (in milliseconds) before a cached segment entry expires. After this, the SDK re-fetches the segments. Default is 60000 milliseconds.
segmentsApiTimeout
optional
numberThe maximum time (in milliseconds) to wait for a response when calling the ODP Segments API. Default is 10000 milliseconds.
segmentManager
optional
OdpSegmentManagerA custom implementation of the OdpSegmentManager that handles how segments are fetched and managed. Override this for advanced use cases.
eventFlushInterval
optional
numberHow often (in milliseconds) to flush queued ODP events to the ODP server. Works similarly to batch processing in event handling.
eventBatchSize
optional
numberNumber of events to accumulate before triggering a flush to the server. Helps reduce the number of network calls.
eventApiTimeout
optional
numberThe maximum time (in milliseconds) to wait for the ODP Events API to respond. Controls timeout behavior for event dispatching.
eventManager
optional
OdpEventManagerA custom implementation of the OdpEventManager that manages how events are queued and dispatched. Useful for extending or overriding default behavior.
userAgentParser
optional
UserAgentParserA utility to parse the user agent string, typically used to enrich event data with device or browser info.

VUID Manager

ODP uses various identifiers unique to a specific customer to track their data. One such identifier is the VUID, which is associated with a specific device. Since VUID tracking is opt-in, it is only used if a VUID manager is provided during instantiation. Additionally, if enableVuid: false is specified when creating the VUID manager, any previously stored VUID-related data on the device is cleared.

import {
  createInstance,
  createPollingProjectConfigManager,
  createBatchEventProcessor,
  createOdpManager,
  createVuidManager
} from "@optimizely/optimizely-sdk";


const pollingConfigManager = createPollingProjectConfigManager({
  sdkKey: "YOUR_SDK_KEY",
})

const batchEventProcessor = createBatchEventProcessor()

const odpManager = createOdpManager()

const vuidManager = createVuidManager({
  enableVuid: true
});


const optimizelyClient = createInstance({
  projectConfigManager: pollingConfigManager,
  eventProcessor: batchEventProcessor,
  odpManager: odpManager,
  vuidManager: vuidManager,
});

To customize the behavior of the VUID manager, you can use the following options of VuidManagerOptions:

OptionTypeDescription
vuidCache
optional
Store<string>A custom cache implementation used to store VUID locally.
enableVuid
optional
boolean

A flag to enable or disable VUID tracking.

If false (default behavior), the VUID is disabled, and any previously cached VUID data is cleared from the provided cache.

If true, the VUID is managed and used for tracking.

Dispose of the client

close method

For effective resource management with the JavaScript SDK, you must properly close the Optimizely client instance when it is no longer needed. You can do so by calling optimizely.close().

The .close() method ensures that the background tasks and queues associated with the instance are properly released. This is essential for preventing memory leaks and ensuring that the application runs efficiently, especially in environments where resources are limited or in applications that create and dispose of many instances over their lifecycle.

disposable config

It is also possible to make the instance of Optimizely client disposable by passing disposable: true in the config. All the background processing is turned off (no datafile polling, no event batching) so that the instance can be garbage collected when all reference to it ceases to exist, even if the close() method is not called. Without it, the SDK instance might not get garbage collected if the close() method is not called. This is particularly beneficial in situations where an instance of the SDK is created per request, and explicitly calling close() on the instances are inconvenient or impossible (for example, server-side rendering, edge environments, and so on).

See Close Optimizely Feature Experimentation JavaScript SDK on application exit.

Source files

The source code files containing the implementation for the JavaScript SDK are available on GitHub.