Dev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideProduct feedbackGitHubNuGetDev CommunitySubmit a ticketLog In

Create custom analytics integration

Describes how to create and enable a new custom integration and troubleshoot common and potential issues

Custom analytics integrations let you build your own analytics integrations on top of Optimizely Web Experimentation with the following benefits:

  • Flexibility in timing and data sent to third-party analytics tools.
  • Improved data consistency between Optimizely Web Experimentation and third-party analytics tools.
  • Opportunity to reduce the number of events sent to third-party analytics tools, which may reduce costs for analytics tools that charge per event.
  • A standardized process for experiment setup, reducing the number of mistakes from selecting incorrect custom dimensions or values.

You can find example integrations in the GitHub library.



If you have built any open source integrations, you can contribute them to the GitHub library. Email [email protected] to begin the process of submitting a contribution.

Create a new integration

  1. Go to Settings > Integrations.

  2. Click Create Analytics Integration. You have two options:

    • Click Using Visual Editor to write your own custom integration via the integration builder screen
    • Click Using JSON to create a new instance of a custom analytics integration using JSON. This is most commonly used when copying an integration from our GitHub library, a third-party knowledge base, or from another project in your account.



See Troubleshoot custom analytics integrations for solutions to common issues.

Visual Editor

The visual editor in the integration builder has three main components:

  • Editable Fields menu
  • Track Campaign Decision custom code field
  • Code Assistant list (hidden by default)

Editable Fields

You can add optional fields to your integration. Each field defines a property that you can customize per experiment. For example, you could provide a field for a custom dimension with a default value set in the integration builder. When you use the integration for a single campaign, you can override the default value for that campaign.

Each field requires an API name to reference it in JavaScript. In the example above, use a field with the API name custom_dimension, which you can reference in the custom JavaScript as extension.custom_dimension.

Examples of editable fields include:

  • Public API Key – Example: Special token required to send data to the integration.
  • Attribute to attach experiment info – Example: Google Analytics custom dimensions or Adobe Analytics eVar/prop
  • String value that needs to change – Example: Custom tracker for Google Analytics



The Optimizely client.js files exposes any editable field or custom code added to an integration. Do not put private keys or passwords here.

You can use the following variables in your JavaScript code:

campaignIdstringThe ID of the campaign into which the user was bucketed
experimentIdstringThe ID of the experiment into which the user was bucketed
variationIdstringThe ID of the variation into which the user was bucketed
isHoldbackbooleanWhether the user fell into the campaign holdback
campaignobjectCampaign data
┗campaign.policystringPersonalization campaigns may have values of 'equal_priority' , 'ordered', or 'random'.
A/B tests can have values of 'multivariate' or 'single_experiment'
extensionobjectThe fields configured for the extension

Create as JSON

You can create a custom analytics integration faster by using JSON instead of the Visual Editor.

To see the JSON of an existing extension, click Edit JSON… for a custom integration. You can copy all JSON code from a custom analytics integration to another project: in the target project. Use the Using JSON option when creating a new custom analytics integration.

Enable an integration

Before you can start using an integration in any experiments, enable it in the dashboard by setting the integration to On.



Enabling integrations also includes them in your project snippet.

Some integrations do not require you to define any custom properties for each experiment (such as custom dimension for Google Analytics). In these cases, you can enable the integration once and do not have to enable it every time you create a new experiment.

To enable the integration by default for new experiments:

  1. Go to the Settings for your custom integration.
  2. Check the Enable this integration by default for all new experiments box.

You can see the setting for all experiments in the Integration Details section in the main Integrations dashboard.

Custom code and timing

The custom JavaScript in the Track Campaign Decision tab runs every time a bucketing decision is made for a campaign. This hook is useful for tracking the experiments and variations into which a visitor was bucketed.



Custom integration code does not execute while in Preview Mode. This is consistent with the built-in out of the box integrations. For more details about the timing of custom code in general, see custom code and timing in Optimizely.


The JavaScript for custom integrations executes on JavaScript API campaignDecided. At a high level, the order of operations for the Optimizely client is:

  1. Project JavaScript.
  2. Evaluate pages.
  3. Evaluate campaigns and experiments on active pages.
  4. Execute custom integration code when campaignDecided triggers (for each experiment or campaign).
  5. Execute shared code for an experiment.
  6. Execute variation code for an experiment’s variation.

For more details, see Snippet order of activation.

Use getDecisionString with custom analytics integrations

The [getDecisionString]( and [getDecisionObject]( APIs make it easier to write custom analytics integrations. These APIs consolidate all data about a campaign decision into a string or object to pass it to a third party analytics provider. You can see examples in our article on analytics strings.

However, these APIs may return a null value. This can happen when a decision is made, but the user is not bucketed into the campaign. For example, if a visitor is on a page where a campaign is running, but they do not match the audience conditions for the campaign, the campaignDecided event fires. The APIs return null because the visitor is not bucketed in the campaign. If these APIs return null, you may not want to send anything to your third party analytics because there is no decision to track.