Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

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

Upgrade the JavaScript SDK from v5 to v6

Steps to upgrade the Feature Experimentation JavaScript SDK from previous versions to version 6.0.0+.

This documentation is for the JavaScript SDK versions 6 and later.

For versions 5.3.5 and earlier, see JavaScript (Browser) SDK or JavaScript (Node) SDK.

See the SDK compatibility matrix documentation for a list of current SDK releases and the features they support.

This guide helps you migrate your implementation from Optimizely JavaScript SDK v5 and earlier to v6. The new version introduces several architectural changes that provide more flexibility and control over SDK components.

Major Changes

In v6, the SDK architecture has been modularized to give you more control over different components:

  • The monolithic createInstance call is now split into multiple factory functions.
  • Core functionality (project configuration, event processing, ODP, VUID, logging, and error handling) is now configured through dedicated components created through factory functions, giving you greater flexibility and control in enabling/disabling certain components and allowing optimizing the bundle size for frontend projects.
  • Event dispatcher interface has been updated to use Promises.
  • onReady Promise behavior has changed.

Client Initialization

v5 (Before)

import { createInstance } from '@optimizely/optimizely-sdk';

const optimizely = createInstance({
  sdkKey: '<YOUR_SDK_KEY>',
  datafile: datafile, // optional
  datafileOptions: {
    autoUpdate: true,
    updateInterval: 300000, // 5 minutes
  },
  eventBatchSize: 10,
  eventFlushInterval: 1000,
  logLevel: LogLevel.DEBUG,
  errorHandler: { handleError: (error) => console.error(error) },
  odpOptions: {
    disabled: false,
    segmentsCacheSize: 100,
    segmentsCacheTimeout: 600000, // 10 minutes
  }
});

v6 (After)

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

// Create a project config manager
const projectConfigManager = createPollingProjectConfigManager({
  sdkKey: '<YOUR_SDK_KEY>',
  datafile: datafile, // optional
  autoUpdate: true,
  updateInterval: 300000, // 5 minutes in milliseconds
});

// Create an event processor
const eventProcessor = createBatchEventProcessor({
  batchSize: 10,
  flushInterval: 1000,
});

// Create an ODP manager
const odpManager = createOdpManager({
  segmentsCacheSize: 100,
  segmentsCacheTimeout: 600000, // 10 minutes
});

// Create a VUID manager (optional)
const vuidManager = createVuidManager({
  enableVuid: true
});

// Create a logger
const logger = createLogger({
  level: DEBUG
});

// Create an error notifier
const errorNotifier = createErrorNotifier({
  handleError: (error) => console.error(error)
});

// Create the Optimizely client instance
const optimizely = createInstance({
  projectConfigManager,
  eventProcessor,
  odpManager,
  vuidManager,
  logger,
  errorNotifier
});

In case an invalid config is passed to createInstance, it returned null in v5. In v6, it will throw an error instead of returning null.

Project Configuration Management

In v6, datafile management must be configured by passing in a projectConfigManager. Choose one of the following:

Polling Project Config Manager

For automatic datafile updates.

const projectConfigManager = createPollingProjectConfigManager({
  sdkKey: '<YOUR_SDK_KEY>',
  datafile: datafileString, // optional
  autoUpdate: true,
  updateInterval: 60000, // 1 minute
  urlTemplate: 'https://custom-cdn.com/datafiles/%s.json' // optional
});

Static Project Config Manager

When you want to manage datafile updates manually or want to use a fixed datafile.

const projectConfigManager = createStaticProjectConfigManager({
  datafile: datafileString,
});

Event Processing

In v5, a batch event processor was enabled by default. In v6, an event processor must be instantiated and passed in explicitly to createInstance through the eventProcessor option to enable event processing, otherwise no events are dispatched. v6 provides the following two types of event processors:

Batch Event Processor

Queues events and sends them in batches.

const batchEventProcessor = createBatchEventProcessor({
  batchSize: 10, // optional, default is 10
  flushInterval: 1000, // optional, default 1000 for browser
});

Forwarding Event Processor

Sends events immediately.

const forwardingEventProcessor = createForwardingEventProcessor();

Custom event dispatcher

In both v5 and v6, custom event dispatchers must implement the EventDispatcher interface. In v6, the EventDispatcher interface has been updated so that the dispatchEvent method returns a Promise instead of calling a callback.

In v5 (Before).

export type EventDispatcherResponse = {
  statusCode: number  
}

export type EventDispatcherCallback = (response: EventDispatcherResponse) => void

export interface EventDispatcher {
  dispatchEvent(event: EventV1Request, callback: EventDispatcherCallback): void
}

In v6 (After).

export type EventDispatcherResponse = {
  statusCode?: number  
}

export interface EventDispatcher {
  dispatchEvent(event: LogEvent): Promise<EventDispatcherResponse>
}

ODP Management

In v5, ODP functionality was configured through odpOptions and enabled by default. In v6, instantiate an OdpManager and pass to createInstance to enable ODP.

v5 (Before)

const optimizely = createInstance({
  sdkKey: '<YOUR_SDK_KEY>',
  odpOptions: {
    disabled: false,
    segmentsCacheSize: 100,
    segmentsCacheTimeout: 600000, // 10 minutes
    eventApiTimeout: 1000,
    segmentsApiTimeout: 1000,
  }
});

v6 (After)

const odpManager = createOdpManager({
  segmentsCacheSize: 100,
  segmentsCacheTimeout: 600000, // 10 minutes
  eventApiTimeout: 1000,
  segmentsApiTimeout: 1000,
  eventBatchSize: 5, // Now configurable in browser
  eventFlushInterval: 3000, // Now configurable in browser
});

const optimizely = createInstance({
  projectConfigManager,
  odpManager
});

To disable ODP functionality in v6, simply do not provide an ODP Manager to the client instance.

VUID Management

In v6, VUID tracking is disabled by default and must be explicitly enabled by createing a vuidManager with enableVuid set to true and passing it to createInstance.

const vuidManager = createVuidManager({
  enableVuid: true, // Explicitly enable VUID tracking
});

const optimizely = createInstance({
  projectConfigManager,
  vuidManager
});

Error Handling

Error handling in v6 uses a new errorNotifier object.

v5 (Before)

const optimizely = createInstance({
  errorHandler: {
    handleError: (error) => {
      console.error("Custom error handler", error);
    }
  }
});

v6 (After)

const errorNotifier = createErrorNotifier({
  handleError: (error) => {
    console.error("Custom error handler", error);
  }
});

const optimizely = createInstance({
  projectConfigManager,
  errorNotifier
});

Logging

Logging in v6 is disabled by defualt, and must be enabled by passing in a logger created through a factory function.

v5 (Before)

const optimizely = createInstance({
  logLevel: LogLevel.DEBUG
});

v6 (After)

import { createLogger, DEBUG } from "@optimizely/optimizely-sdk";

const logger = createLogger({
  level: DEBUG
});

const optimizely = createInstance({
  projectConfigManager,
  logger
});

onReady Promise Behavior

The onReady() method behavior has changed in v6. In v5, onReady() fulfilled with an object that had the following two fields: success and reason. If the instance failed to initialize, success would be false and reason contained an error message. In v6, if onReady() fulfills, that means the instance is ready to use, the fulfillment value is of unknown type and does not to be inspected. If the promise rejects, that means there was an error during initialization.

v5 (Before)

optimizely.onReady().then(({ success, reason }) => {
  if (success) {
    // optimizely is ready to use
  } else {
    console.log(`initialization unsuccessful: ${reason}`);
  }
});

v6 (After)

optimizely
  .onReady()
  .then(() => {
    // optimizely is ready to use
    console.log("Client is ready");
  })
  .catch((err) => {
    console.error("Error initializing Optimizely client:", err);
  });

Migration Examples

Basic example with SDK key

v5 (Before)

import { createInstance } from '@optimizely/optimizely-sdk';

const optimizely = createInstance({
  sdkKey: '<YOUR_SDK_KEY>'
});

optimizely.onReady().then(({ success }) => {
  if (success) {
    // Use the client
  }
});

v6 (After)

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

const projectConfigManager = createPollingProjectConfigManager({
  sdkKey: '<YOUR_SDK_KEY>'
});

const optimizely = createInstance({
  projectConfigManager
});

optimizely
  .onReady()
  .then(() => {
    // Use the client
  })
  .catch(err => {
    console.error(err);
  });

Complete Example with Real-Time Segments for Feature Experimentation and event batching

v5 (Before)

import { createInstance, LogLevel } from '@optimizely/optimizely-sdk';

const optimizely = createInstance({
  sdkKey: '<YOUR_SDK_KEY>',
  datafileOptions: {
    autoUpdate: true,
    updateInterval: 60000 // 1 minute
  },
  eventBatchSize: 3,
  eventFlushInterval: 10000, // 10 seconds
  logLevel: LogLevel.DEBUG,
  odpOptions: {
    segmentsCacheSize: 10,
    segmentsCacheTimeout: 60000 // 1 minute
  }
});

optimizely.notificationCenter.addNotificationListener(
  enums.NOTIFICATION_TYPES.TRACK,
  (payload) => {
    console.log("Track event", payload);
  }
);

v6 (After)

import { 
  createInstance, 
  createPollingProjectConfigManager,
  createBatchEventProcessor,
  createOdpManager,
  createLogger,
  DEBUG,
  NOTIFICATION_TYPES
} from '@optimizely/optimizely-sdk';

const projectConfigManager = createPollingProjectConfigManager({
  sdkKey: '<YOUR_SDK_KEY>',
  autoUpdate: true,
  updateInterval: 60000 // 1 minute
});

const batchEventProcessor = createBatchEventProcessor({
  batchSize: 3,
  flushInterval: 10000, // 10 seconds
});

const odpManager = createOdpManager({
  segmentsCacheSize: 10,
  segmentsCacheTimeout: 60000 // 1 minute
});

const logger = createLogger({
  level: DEBUG
});

const optimizely = createInstance({
  projectConfigManager,
  eventProcessor: batchEventProcessor,
  odpManager,
  logger
});

optimizely.notificationCenter.addNotificationListener(
  NOTIFICATION_TYPES.TRACK,
  (payload) => {
    console.log("Track event", payload);
  }
);

For complete implementation examples, refer to the Optimizely JavaScript SDK documentation.