Optimizely will be sunsetting Full Stack Experimentation on July 29, 2024. See the recommended Feature Experimentation migration timeline and documentation.

Dev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Client-side implementation tips

This topic describes tips and considerations for installing Optimizely Full Stack JavaScript on a client (browser) instead of a server.

Datafile management for JavaScript client-side implementation

Include datafile as a synchronous script tag

This approach allows you to include the datafile as a script. The script will define a global variable, window.optimizelyDatafile, that contains the datafile contents.

Include the datafile script tag above your app code that creates a new Optimizely client instance:

<script src="https://cdn.optimizely.com/datafiles/<YOUR ENVIRONMENT SDKKEY>.json/tag.js"></script>

In your app code, reference that variable when creating a new Optimizely client instance:

var optimizelyClientInstance = window.optimizelySdk.createInstance({
    datafile: window.optimizelyDatafile
Always uses the most up-to-date datafile contents.
Blocking request; no flickering.
* Blocking request introduces slight page-load latency.

Synchronize the datafile between client and server

Consider this approach if your organization is already using the Optimizely SDK on the server side. For more information, see Multiple SDKs.

Load datafile contents via Edge Side Includes (ESI)

This approach is best for minimizing page flicker. It only requires one-time ESI setup and doesn't require server-side datafile management service.

It does require a CDN vendor that supports ESI, such as Fastly or Akamai.

Datafile contents inline in page source.
No request needed on the client side.
* One-time setup.
* May present challenges for lower-level environments: ESI is a CDN feature, so you need a solution in place to serve the datafile when developing locally.

Fetch datafile using automatic datafile management

You can implement the automatic datafile management functionality to handle datafile updates. This approach offers an easy implementation with good datafile freshness.

No need for server-side datafile management: fetch directly to the client side from cdn.optimizely.com.
Fast implementation: no need to write datafile management code.
Will always have the most up to date datafile contents.
No blocking request that affects page load.
Asynchronous: must wait for datafile fetch.
Can not use localStorage caching for fast synchronous initialization.

User identifiers

To obtain user identifiers (IDs), use one of these methods:

  • Recommended: Use IDs from a client-side analytics service like Google Analytics Client ID or Adobe Analytics Visitor ID. Because these IDs are generated asynchronously, a first-time visitor probably won’t have a unique IDs on their first page view.
  • Use cookies with unique visitor IDs.

Link-click tracking

The Optimizely JavaScript SDK does not use localStorage and consequently doesn’t maintain a queue of pendingEvents (which Optimizely Web does automatically). This means the browser will likely cancel a number of link-click tracking calls as users are being redirected.

A possible solution is to pass a parameter to the subsequent page URL and fire an event on that page.

Wrapper for Activate and Track

If you create a lightweight wrapper around Activate and Track, you can call those methods in various components of your client-side application code without full context.

For example:

  • Your wrapper calls will pass userAttributes and userId into the Track and Activate calls. This way, you can bind a click-tracking call to a button by using the name of the event: <button onclick=”clientWrapper.track(‘clicked_submit’);”>Submit</button>
  • Your clientWrapper.track call will pass the event name into the client.track method, along with the userId and userAttributes.

Useful wrapper features would include:

  • Automatic datafile downloading and caching (through localStorage)
  • User ID + attributes memoization
  • Render blocking until datafile is ready via a React API
  • Optimizely timeout (only block rendering up to the number of milliseconds you specify)
  • Event queuing for track, which allows track calls to happen before the datafile is downloaded



When you implement an Optimizely SDK or wrapper, make sure to use the correct userId for your use case.

Reserve word for Optimizely Web

If you use both Optimizely Web and Optimizely Full Stack client-side, then avoid the reserve word optimizely in your window-scoped variable names in Full Stack. This word is reserved for Optimizely web, and using it in your Full Stack code can cause problems for Optimizely Web, such as breaking the visual editor.

// name your client-side Optimizely instance something like this:
const optimizelyClientInstance = optimizelySDK.createInstance({
sdkKey: '<Your_SDK_Key>'

// AVOID naming your client-side instance this:
const optimizely = optimizelySDK.createInstance({
sdkKey: '<Your_SDK_Key>'

React & React Native SDKs

Our React SDK simplifies integration with client-side and server-side React applications. See the GitHub README for features, use cases, and implementation instructions.


Please contact support if you need help with your implementation.