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 React SDK

Initialize the Optimizely Feature Experimentation React SDK in your application.

Use the createInstance method to initialize the React SDK and instantiate a Client instance. Each client corresponds to the datafile representing the state of a project for a certain environment.

Minimum SDK version

v4.0.0+

For versions 3.x and earlier, see React SDK prior to v4.

Description

The createInstance method accepts a modular configuration object. Unlike v3, where options like sdkKey, datafile, and event batching were top-level parameters, v4 uses dedicated factory functions for each component.

Important: You must use createInstance from @optimizely/react-sdk, not from @optimizely/optimizely-sdk. A client created directly from the JS SDK will not work correctly with <OptimizelyProvider> and hooks.

Parameters

The following table lists the required and optional parameters for the createInstance configuration object:

ParameterTypeDescription
projectConfigManagerOpaqueConfigManagerRequired. Manages the datafile. Create with createPollingProjectConfigManager or createStaticProjectConfigManager.
eventProcessorOpaqueEventProcessorProcesses and dispatches events. Create with createBatchEventProcessor or createForwardingEventProcessor. Opt-in — if not provided, no events are dispatched.
loggerOpaqueLoggerLogger instance. Create with createLogger. Opt-in — disabled by default.
errorNotifierOpaqueErrorNotifierError notification handler. Create with createErrorNotifier.
userProfileServiceUserProfileServiceSynchronous user profile service for sticky bucketing.
userProfileServiceAsyncUserProfileServiceAsyncAsynchronous user profile service for sticky bucketing.
defaultDecideOptionsOptimizelyDecideOption[]Default options applied to all decide calls.
odpManagerOpaqueOdpManagerODP manager for audience segments and events. Create with createOdpManager. Opt-in — if not provided, ODP is disabled.
vuidManagerOpaqueVuidManagerVisitor UID manager. Create with createVuidManager. Opt-in — disabled by default.
disposablebooleanWhen true, marks the client as single-use for SSR (can be garbage collected without calling close()).

Returns

Instantiates a Client instance. In v4, createInstance throws an error on invalid config (v3 returned null).

Example

Instantiate with a datafile

Use createStaticProjectConfigManager for a fixed datafile with no polling:

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

const optimizely = createInstance({
  projectConfigManager: createStaticProjectConfigManager({
    datafile: window.optimizelyDatafile,
  }),
  eventProcessor: createForwardingEventProcessor(),
});

Instantiate with the SDK key

Use createPollingProjectConfigManager to have the SDK fetch and poll for the datafile:

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

const optimizely = createInstance({
  projectConfigManager: createPollingProjectConfigManager({
    sdkKey: "YOUR_SDK_KEY",
  }),
  eventProcessor: createBatchEventProcessor(),
});

Instantiate with both SDK key and datafile

Use the given datafile immediately, then fetch and poll for updates in the background:

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

const optimizely = createInstance({
  projectConfigManager: createPollingProjectConfigManager({
    sdkKey: "YOUR_SDK_KEY",
    datafile: window.optimizelyDatafile,
    autoUpdate: true,
  }),
  eventProcessor: createBatchEventProcessor(),
});

Render an OptimizelyProvider with a client and user

To use the React SDK hooks inside your app, render an OptimizelyProvider as the parent of your root app component. Provide your client as the client prop and a user object:

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

const optimizely = createInstance({
  projectConfigManager: createPollingProjectConfigManager({
    sdkKey: "YOUR_SDK_KEY",
  }),
  eventProcessor: createBatchEventProcessor(),
});

export default function App() {
  return (
    <OptimizelyProvider client={optimizely} user={{ id: "<YOUR_USER_ID>" }}>
      <App />
    </OptimizelyProvider>
  );
}

Render an OptimizelyProvider in VUID-only mode

For VUID-only mode (no user ID), pass an empty object as the user prop. The SDK uses an auto-generated visitor UID for decisions and event tracking. You must enable VUID by passing createVuidManager and createOdpManager to createInstance:

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

const optimizely = createInstance({
  projectConfigManager: createPollingProjectConfigManager({
    sdkKey: "YOUR_SDK_KEY",
  }),
  eventProcessor: createBatchEventProcessor(),
  odpManager: createOdpManager(),
  vuidManager: createVuidManager({
    enableVuid: true,
  }),
});

export default function App() {
  return (
    <OptimizelyProvider client={optimizely} user={{}}>
      <App />
    </OptimizelyProvider>
  );
}

Config manager factories

FactoryUse case
createPollingProjectConfigManager({ sdkKey, datafile?, autoUpdate?, updateInterval?, urlTemplate? })Fetches and polls for datafile updates. sdkKey is required.
createStaticProjectConfigManager({ datafile })Uses a fixed datafile with no polling.

Polling config manager options

OptionTypeDescription
sdkKeystringRequired. The key associated with an environment in the project.
datafilestring | objectOptional initial datafile (JSON string or parsed object).
autoUpdatebooleanWhen true, automatic updates are enabled. Default: true.
updateIntervalnumberUpdate interval in milliseconds. Minimum: 1000. Default: 300000 (5 minutes).
urlTemplatestringFormat string for the datafile URL. %s is replaced with the sdkKey.

Event processor factories

FactoryUse case
createBatchEventProcessor({ batchSize?, flushInterval? })Batches events before dispatching.
createForwardingEventProcessor()Forwards each event immediately.
📘

Note

Event processing is opt-in in v4. If no eventProcessor is passed to createInstance, no events are dispatched. To disable event dispatching, simply omit the eventProcessor parameter.

Other configurable modules

FactoryUse case
createOdpManager()Enables ODP integration (audience segments, events).
createVuidManager({ enableVuid })Enables visitor UID tracking.
createErrorNotifier({ handleError })Configures error notification.
createLogger({ logLevel })Creates a logger instance. See Customize the React SDK logger.

Full client creation example

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

const optimizely = createInstance({
  projectConfigManager: createPollingProjectConfigManager({
    sdkKey: "YOUR_SDK_KEY",
    autoUpdate: true,
    updateInterval: 60000,
  }),
  eventProcessor: createBatchEventProcessor({
    batchSize: 10,
    flushInterval: 2000,
  }),
  odpManager: createOdpManager(),
  logger: createLogger({ logLevel: DEBUG }),
  errorNotifier: createErrorNotifier({
    handleError: (error) => console.error("Custom error handler", error),
  }),
});

Notes

Dispose of the client

For effective resource management, properly close the Optimizely client instance when it is no longer needed by calling optimizely.close().

The .close() method ensures that the processes and queues associated with the instance are properly released. This is essential for preventing memory leaks, especially in environments where resources are limited.

For SSR per-request instances, you can set disposable: true in createInstance so the instance can be garbage collected without explicitly calling close().

See Close Optimizely on application exit.

Server-side rendering

The React SDK supports server-side rendering (SSR). A pre-fetched datafile is required for SSR — without one, the SDK cannot make decisions during server rendering.

Per-request client

Create a client with createStaticProjectConfigManager and a pre-fetched datafile. Use disposable: true so the instance can be garbage collected without explicitly calling close():

import { useMemo } from "react";
import {
  createInstance,
  createStaticProjectConfigManager,
  OptimizelyProvider,
  OptimizelyDecideOption,
  useDecide,
} from "@optimizely/react-sdk";

export default function Page({ datafile, userId }) {
  const optimizely = useState(() =>
    createInstance({
      projectConfigManager: createStaticProjectConfigManager({ datafile }),
      defaultDecideOptions: [OptimizelyDecideOption.DISABLE_DECISION_EVENT],
      disposable: true,
    })
  );

  return (
    <OptimizelyProvider client={optimizely} user={{ id: userId }}>
      <MyComponent />
    </OptimizelyProvider>
  );
}

function MyComponent() {
  const { decision, isLoading } = useDecide("flag1");
  if (isLoading) return null;
  return decision.enabled ? <p>Feature enabled</p> : <p>Feature disabled</p>;
}

Module-level client

For a long-lived server process, create a singleton client at the module level with createPollingProjectConfigManager:

import {
  createInstance,
  createPollingProjectConfigManager,
  createBatchEventProcessor,
  OptimizelyProvider,
  OptimizelyDecideOption,
  useDecide,
} from "@optimizely/react-sdk";

const optimizely = createInstance({
  projectConfigManager: createPollingProjectConfigManager({
    sdkKey: process.env.NEXT_PUBLIC_OPTIMIZELY_SDK_KEY,
    datafile: preloadedDatafile,
  }),
  eventProcessor: createBatchEventProcessor(),
  defaultDecideOptions: [OptimizelyDecideOption.DISABLE_DECISION_EVENT],
});

function App() {
  return (
    <OptimizelyProvider client={optimizely} user={{ id: "user1" }}>
      <MyComponent />
    </OptimizelyProvider>
  );
}

getQualifiedSegments

A standalone async utility that fetches qualified ODP audience segments for a user, given a datafile:

import { getQualifiedSegments } from "@optimizely/react-sdk";

const { segments, error } = await getQualifiedSegments(userId, datafile);
ArgumentTypeDescription
userIdstringThe user ID to fetch qualified segments for.
datafilestring | Record<string, any>The Optimizely datafile (JSON object or string).

Returns Promise<QualifiedSegmentsResult>{ segments: string[], error: Error | null }

📘

Note

The ODP segment fetch adds latency to server rendering. Consider caching the result per user to avoid re-fetching on every request.

React Server Components

The SDK provides a server-safe entry point via the react-server export condition. Frameworks that support this condition (e.g., Next.js App Router) automatically resolve @optimizely/react-sdk to the server entry point when importing from a Server Component. This entry point excludes hooks and Provider (which use client-only React APIs).

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

export default async function ServerComponent() {
  const client = createInstance({
    projectConfigManager: createStaticProjectConfigManager({ datafile }),
  });

  await client.onReady();

  const userContext = client.createUserContext("user-123");
  const decision = userContext.decide("flag-key");

  client.close();

  return decision.enabled ? <NewFeature /> : <Default />;
}

SSR limitations

  • Datafile required – SSR requires a pre-fetched datafile. Using sdkKey alone falls back to a failed decision.
  • ODP segments – ODP audience segments require async I/O and are not available during server rendering. Use getQualifiedSegments to pre-fetch segments server-side and pass them with the qualifiedSegments prop on OptimizelyProvider.

For framework-specific SSR patterns, see the Next.js Integration Guide.

Source files

The language and platform source files containing the implementation for the React SDK are available on GitHub.