Initialize the JavaScript SDK v6+
How to initialize the Optimizely Feature Experimentation JavaScript SDK versions 6 and above in your application.
Use the createInstance
method to initialize the JavaScript SDK and instantiate an instance of the Optimizely client class that exposes API methods like the decide methods. Each client corresponds to the datafile, representing the state of a project for a certain environment.
Minimum SDK version
v6.0.0+
For versions 5.3.5 and below, 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.
Description
The createInstance
method accepts a configuration object to configure the Optimizely client instance.
Some parameters are optional, you can opt in to use those features by providing the relevant configuration. For example, you can configure an error handler and logger to catch issues, an event dispatcher to manage network calls, and a user profile service to ensure sticky bucketing.
Parameters
The following parameters are the required and optional properties of the configuration object:
Parameter | Type | Description |
---|---|---|
projectConfigManager | OpaqueConfigManager |
|
eventProcessor | OpaqueEventProcessor |
If this is not set, no events are dispatched. |
odpManager | OpaqueOdpManager |
You should provide an instance of |
vuidManager | OpaqueVuidManager |
You should provide an instance of NodeJS environments do not have support for |
logger | OpaqueLogger | A logger implementation to log messages. You should provide an instance of |
errorNotifier | OpaqueErrorNotifier |
|
userProfileService | UserProfileService | A user profile service. An object with |
userProfileServiceAsync | UserProfileServiceAsync | An async version of user profile service. An object with |
jsonSchemaValidator | { validate(jsonObject: unknown): boolean; } | To perform JSON schema validation on datafiles. Validator must have a Skipping JSON schema validation enhances performance during initialization. |
defaultDecideOptions | OptimizelyDecideOption[] | Array of When you construct the Optimizely client with this parameter, it sets default decide options which are applied to all the decide calls made during the lifetime of the Optimizely client. Also, you can pass options to individual decide methods (does not override defaults). See OptimizelyDecideOption. |
disposable | boolean | Make the instance disposable, which means all 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 This is particularly beneficial in situations where an instance of the SDK is created per request, and explicitly calling |
clientEngine | string |
This is useful when a wrapper client (For example, React SDK) is created around the SDK. |
clientVersion | string |
|
Returns
Returns an instance of the Client
interface or throws an error if an invalid configuration is passed.
Examples
In order to to instantiate using an SDK key, obtain the SDK Key from your project's settings and pass it in.
- Go to Settings > Environments.
- 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
methodonReady
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 via 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 will be 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:
Polling 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
:
Option | Type | Description |
---|---|---|
sdkKey | string | The key associated with an environment in the project. |
datafile | string | The JSON string representing the project. |
jsonSchemaValidator | object | To perform JSON schema validation on datafiles. Skipping validation enhances performance during initialization |
autoUpdate | boolean | When |
updateInterval | number | When 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 | string | A format string used to build the URL from which the SDK requests datafiles. Instances of |
datafileAccessToken | string | A bearer token used to authenticate requests when fetching the secure environment and needs authorization. |
cache | Store | 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.json();
return datafile;
};
const staticConfigManager = createStaticProjectConfigManager({
datafile: 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 following options of StaticConfigManagerConfig
:
Option | Type | Description |
---|---|---|
datafile | string | The JSON string representing the project. |
jsonSchemaValidator | object | To perform JSON schema validation on datafiles. Skipping validation enhances performance during initialization |
Event processor
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 following options of BatchEventProcessorOptions
:
Option | Type | Description |
---|---|---|
eventDispatcher optional | EventDispatcher | A custom event dispatcher used to send events. If not provided, the default dispatcher is used. |
closingEventDispatcher | EventDispatcher | A specialized custom dispatcher used to send any remaining events when the processor shuts down. |
flushInterval | number | The time interval (in miliseconds) at which the event queue is automatically flushed. Default is 1000 milliseconds for browser and React Native and 30 seconds for NodeJS. |
batchSize | number | The number of events to accumulate before sending them as a batch. Default is 10. |
eventStore | Store | A custom cache implementation to store events temporarily to track failed events to retry later on. |
Forwarding 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 following options:
Option | Type | Description |
---|---|---|
eventDispatcher optional | EventDispatcher | A custom event dispatcher used to send events. If not provided, the default dispatcher is used. |
OdpManager
OdpManager
contains the logic supporting Real-Time Segments for Feature Experimentation-related features, including audience segments, ODP events, and VUID tracking.
To enable Real-time Segments for Feature Experimentation you have to pass the OdpManager
and configure Real-Time Segments 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 following options of OdpManagerOptions
:
Option | Type | Description |
---|---|---|
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 | number | The maximum number of user segment entries to keep in the cache. Default is 1000. |
segmentsCacheTimeout | number | The time (in milliseconds) before a cached segment entry expires. After this, the SDK re-fetches the segments. Default is 60000 milliseconds. |
segmentsApiTimeout | number | The maximum time (in milliseconds) to wait for a response when calling the ODP Segments API. Default is 10000 milliseconds. |
segmentManager | OdpSegmentManager | A custom implementation of the |
eventFlushInterval | number | How often (in miliseconds) to flush queued ODP events to the ODP server. Works similarly to batch processing in event handling. |
eventBatchSize | number | Number of events to accumulate before triggering a flush to the server. Helps reduce the number of network calls. |
eventApiTimeout | number | The maximum time (in milliseconds) to wait for the ODP Events API to respond. Controls timeout behavior for event dispatching. |
eventManager | OdpEventManager | A custom implementation of the |
userAgentParser | UserAgentParser | A 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 following options of VuidManagerOptions
:
Option | Type | Description |
---|---|---|
vuidCache optional | Store | A custom cache implementation used to store VUID locally. |
enableVuid | 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
close
methodFor 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
disposable
configIt 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, event 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.
Updated 2 days ago