Optimizely Destination

Segment makes it easy to send your data to Optimizely (and lots of other destinations). Once you've tracked your data through our open source libraries we'll translate and route your data to Optimizely in the format they understand. Learn more about how to use Optimizely with Segment.

Getting Started

Segment allows you to track events directly into Optimizely, and record your Optimizely experiments or campaigns back into Segment, allowing you to analyze Optimizely data inside you other downstream tools enabled inside Segment!

Our destination supports both Classic, Optimizely X, or Both.

Required Step

Because the Optimizely destination needs to be on the page right away, Segment can’t load its client side library for you. That means you MUST put the Optimizely javascript snippet on the page. Pop over to Optimizely and click “Settings” to get your custom script and paste it inside your <HEAD> tag BEFORE above your Segment snippet!

The Optimizely script script looks something like this:

<script src="//cdn.optimizely.com/js/#########.js"></script>

Include this snippet on every page you want to run experiments on. This snippet will not change. It’s important that this script is loaded first before Segment’s async script since Optimizely alters the page to run its experiments so we want to make sure that the experiment data is available by the time Segment finishes initializing its Optimizely destination.

On Android

Since Optimizely needs to be initialized as early as possible, you need to supply the API key when you initialize the factory that is registered with the analytics client.

analytics.use(OptimizelyIntegration.createFactory(application, apiKey));

This will initialize the Optimizely SDK under the hood and begin forwarding events and collecting experiment data as defined in your destination settings.

On iOS

Since Optimizely needs to be initialized as early as possible, you need to supply the API key when you initialize the factory that is registered with the analytics client.

[config use:[SEGOptimizelyIntegrationFactory instanceWithToken:apiKey launchOptions:launchOptions]];

This will initialize the Optimizely SDK under the hood and begin forwarding events and collecting experiment data as defined in your destination settings.

Server-side

Currently Optimizely does not accept server-side events.


Track

If you want to track custom events directly to Optimizely, you’d use our track method.

To use events in Optimizely create a Custom Event Goal inside Optimizely’s UI with the exact same name as the event you are recording in your Segment track call. Inside Optimizely’s UI, the Custom Event to track should be an exact string match of the name that is passed from Segment.

We will send any .track() events you record via Optimizely’s trackEvent API by passing it the event name and the revenue (if provided). Read more about how we map the properties.revenue below.

Revenue

Optimizely recognizes revenue, which is part of our E-commerce Spec. To pass in revenue to Optimizely, just send the exact dollar amount of revenue you earned as a revenue property.

Note: Optimizely usually takes revenue in cents instead of dollars so we make that conversion for you automatically.

Segment legacy behavior sends revenue on all events containing properites.revenue. Moving forward, the default behavior for new Segment-Optimizely users will be to send revenue only on Order Completed events as expected by Optimizely X and Classic. If you would like revenue sent only on Order Completed events, be sure that you have the Send Revenue Only on Order Completed Events option enabled in your destination settings page.

Offline Conversions

Optimizely offline conversions are not currently supported through Segment since Optimizely doesn’t have a method for identifying visitors by a userId. That means we’d have to ask you, our cherished user, to keep track of the optimizelyEndUserId, experiments and variations for each visitor to make this work.

If you’d like to hook up to the Optimizely offline conversion API directly you can find the docs here.


Sending Experiment Data to Segment

A key feature of our Optimizely destination is the ability to send your experiment data back into Segment so that you can analyze them in your other analytics providers outside of Optimizely.

There are two methods in which you can do this. In your Optimizely settings, you can opt to choose to send experiment data via .track() or .identify().

send-via-track send-via-identify

Important: Sending via .identify() is NOT recommended as it may have adverse effects since it could lead to many unwanted traits being cached to your user profiles in your other end tools as well as unwanted columns in Segment connected warehouses. It also lacks many additional properties that is collected by the .track() option.

Depending on whether you are running experiments created inside Optimizely Classic or X, the following is what you can expect to be seen inside Segment:

Optimizely Classic

If you are using Optimizely Classic, we are able to send back experiments that are only Immediately Activated. We do not support collecting data of manually or conditionally activated experiments. However, we will be able to track these types of activations if you are using Optimizely X.

Standard or Redirect Experiments

Properties sent via .track() calls:

  • experimentId
  • experimentName
  • variationId
  • variationName
  • referrer (only set if the effective referrer is different than document.referrer, please refer to here)
  • nonInteraction (based on your advanced settings inside Segment)

Example call automatically invoked upon page load:

analytics.track('Experiment Viewed', {
  experimentId: '7561662364',
  experimentName: 'Home Page CTA Button',
  variationId: '7549901603',
  variationName: 'Variation Blue Background',
  nonInteraction: 1
});

Note: the nonInteraction property is set if you have enabled Send Experiment Viewed as a non-interaction event setting.

Trait sent via .identify() calls:

  • experimentName
  • variationName

Example call automatically invoked upon page load:

analytics.identify({
  'Experiment: Home Page CTA Button': 'Variation Blue Background'
});

Note: If you run multiple experiments during a user session, since traits are cached, subsequent experiments would fire .identify() calls that still contain previous experiment data.

Multivariate Experiments

Properties sent via .track() calls:

  • experimentId
  • experimentName
  • variationId
  • variationName
  • sectionName
  • sectionId
  • nonInteraction (based on your advanced settings inside Segment)

    Note: We will concatenate all the variationIds, variationNames, sectionNames, and sectionIds where necessary.

Example call automatically invoked upon page load:

analytics.track('Experiment Viewed', {
  experimentId: '7571581357',
  experimentName: 'Most Popular LoL Champion',
  variationId: '756194997,7563911532'
  variationName: 'Variation Teemo, Variation Corki',
  sectionName: 'Section Top, Section ADC',
  sectionId: '752911997,226194955'
  nonInteraction: 1
});

Note: the nonInteraction property is set if you have enabled Send Experiment Viewed as a non-interaction event setting.

Trait sent via .identify() calls:

  • experimentName
  • variationName

Example call automatically invoked upon page load:

analytics.identify({
  'Experiment: Most Popular LoL Champion': 'Variation Teemo, Variation Corki'
});

Note: If you run multiple experiments during a user session, since traits are cached, subsequent experiments would fire .identify() calls that still contain previous experiment data.

Optimizely X

Our destination supports sending experiment or personalized campaign data when using Optimizely X. Note that we can support all of the available activation types: Immediately, Polling (formerly known in Classic as Conditional), Callback and Manual.

Also note that Optimizely X no longer supports Multivariate experiments.

Standard or Redirect Experiments/Campaigns

Properties sent via .track() calls:

  • campaignName
  • campaignId
  • experimentId
  • experimentName
  • referrer (only set if the effective referrer is different than document.referrer, please refer to here)
  • variationName
  • variationId
  • audienceId
  • audienceName
  • nonInteraction (based on your advanced settings inside Segment)

    Note: campaignName and experimentName will be the same if you create an experiment directly rather than creating an “experience” inside a personalized campaign. However, campaignId will still be auto generated by Optimizely’s API, thus it will be different than the experimentId.

    example-settings

Example call automatically invoked upon page load:

analytics.track('Experiment Viewed', {
  campaignName: 'Countdown to Stranger Things 2',
  campaignId: '7554165405',
  experimentId: '7556781578',
  experimentName: 'What about Barbs?',
  variationId: '7578240035',
  variationName: 'Variation Barbs',
  audienceId: '7527565438',
  audienceName: 'Netflix Bingers',
  nonInteraction: 1
});

Trait sent via .identify() calls:

  • experimentName
  • variationName

Example call automatically invoked upon page load:

analytics.identify({
  'Experiment: What about Barbs?': 'Variation Barbs'
});

Note: If you run multiple experiments during a user session, since traits are cached, subsequent experiments would fire .identify() calls that still contain previous experiment data.

Sending Experiment Viewed events as Non-Interaction for GA

If you’re using GA and the above setting, you’ll likely want to check this setting in the Segment UI for the Optimizely destination:

non-interaction-flag-setting

This will append an additional property in your Experiment Viewed events called nonInteraction and set it to 1. This is to prevent negatively affecting your bounce rate.

Sending Experiment Viewed event properties as Google Analytics Custom Dimensions

If you’re sending your Experiments to GA in the form of track calls, we recommend creating hit-scoped custom dimensions in Google Analytics with titles like Experiment Name and Variation Name, and then mapping the properties to those Custom Dimensions accordingly. For example, if you set Custom Dimension 5 to “Experiment Name” and Custom Dimension 1 to “Variation Name”, here’s how you’d configure the mappings in your Segment <> GA settings pane:

Optimizely X Fullstack

You can also additionally opt to integrate Optimizely X Fullstack:

IMPORTANT: You must be using Optimizely’s Javascipt SDK version 1.3.0 or higher to use Fullstack.

  • 1) Create an Optimizely X Fullstack project.

  • 2) If you have any attributes to track in the event, please create them in our Optimizely dashboard first.

  • 3) Then install the JavaScript SDK before the Segment snippet, just like how you do with the original Optimizely snippet.

  • 4) Create an instance of the JavaScript SDK client and attach it to the global variable window.optimizelyClientInstance. This step must be done before any calls to analytics.track!

  • 5) Call .track() as you normally would and the events should also be sent to the Optimizely Fullstack experiment. We will send the event name, userId, any properties and properties.revenue.

    Important: If you are sending anonymous data to Optimizely Fullstack via their server side SDK and you’d like to send anonymous data of that same user but from the client side, you can pass in an Optimizely specific userId:

    analytics.track('Some event', {}, {
      Optimizely: { userId: 'some anonymousId' }
    });
    

Troubleshooting

Lower Experiment Viewed counts inside Segment and other tools vs. Optimizely unique visitors

The count of the Experiment Viewed may be slightly lower compared to the number of unique visitors seen in Optimizely because Optimizely loads synchronously and Segment loads asynchronously (to ensure pages load as fast as possible). This means that if the user quickly closes or redirects from a given page, sometimes Segment might not have enough time to scrape the experiment data from the global Optimizely object and make its API calls back to Segment or to your other enabled tools.

Sending effective referrer in your automatic page calls

If you are running Redirect Experiments, you might run into a case where the effective referrer is different than the referrer that is captured by .page() calls, such as the default page call in our Segment snippet.

For example, let’s say you run a redirect experiment on page http://home.com that redirects you to http://home-offers.com. Now, if a customer visits your page via an advertisement on Google.com, you want to make sure that the .page() call fired on http://home-offers.com knows that the true referrer was Google.com and NOT http://home.com.

Our Optimizely destination will detect this and send the effective referrer value as a property of the Experiment Viewed event that we send back into Segment. We will also override the context.page.referrer with the effective referrer!

More importantly, in order to send this true referrer value with your default initial .page() call inside the Segment snippet, you can look up window.optimizelyEffectiveReferrer and if it exists, you can pass that into your page call. This is how you might modify your Segment snippet:

<script type="text/javascript">
  !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.1.0";
  analytics.load("YOUR_WRITE_KEY");

  /* MODIFIED SECTION */
  // Hey did Optimizely set an effective referrer?
  if (window.optimizelyEffectiveReferrer) var referrer = window.optimizelyEffectiveReferrer;

  // If they did, override the document.referrer
  referrer ? analytics.page({ referrer: referrer }); : analytics.page();
  /* MODIFIED SECTION */

  }}();
</script>

Supported Sources and Connection Modes

WebMobileServer
📱 Device-based
☁️ Cloud-based

To learn more about about Connection Modes and what dictates which we support, see here.

This destination requires a Device-based Connection Mode for Mobile data. Follow the steps above to ensure you have packaged the Optimizely SDK with Segment’s.

Settings

Segment lets you change these destination settings via your Segment dashboard without having to touch any code.

This is Optimizely expected behavior. This will send revenue only on Order Completed events.

Track Categorized Pages

This will track events to Optimizely for page method calls that have a category associated with them. For example page('Docs', 'Index') would translate to Viewed Docs Index Page.

Track Named Pages

This will track events to Optimizely for page method calls that have a name associated with them. For example page('Signup') would translate to Viewed Signup Page.

The reason this is not recommended is because if you’re running lots of experiments, this could lead to loads of unwanted properties in end tools as well as unwanted columns in Segment connected databases.

Send experiment data to other tools (as a track call)

Sends the experiment and variation information as properties on a track call.

Send `Experiment Viewed` as a non-interaction event

Specifies the Experiment Viewed as a non-interaction event for Google Analytics


If you have any questions or see anywhere we can improve our documentation, please let us know or kick off a conversation in the Segment Community!