How to Opt-Out of Optimizely ( in One Click

What does “waiting for ‘’ mean?

In short, ‘cdn’ means Content Distribution Network and Optimizely is a service that provides A/B Testing for websites. Optimizely makes A/B testing possible by swapping images or changing the structure or style of a web page. To do this, it has to load additional instruction on to the web page being tested.

The reason you are seeing “waiting for” as you are trying to load a site is most likely because the network you are using is somewhat slow. It just happens to be Optimizely information (likely an image page content for the A/B test) that is coming across the network while you are waiting on a slow network connection.

How to Opt-Out of Optimizely in One Click

The quick solution is to create a bookmarklet to opt out of Optimizely for any page that you don’t want Optimizely to load on. To do this:

  • Create a new bookmark in your browser
  • Instead of adding in a URL add the following:
javascript:(function(){window.location += '?optimizely_opt_out=true'}())
  • click the bookmarklet when loading sites that are using Optimizely.

Done! You’ve successfully opted out of Optimizely. You should no longer have to wait on for that page. This should remain in effect until you clear that site’s cookies.

Optimizely is not Bad!

(In fact is pretty awesome)

The reason I wrote this is because a friend tweeted his frustration about waiting on “” The unfortunate part is that, while Optimizely appears to be the culprit of a slow-loading web page, it’s actually far more likely that a slow network connection is to blame.

You probably like Optmizely but you just didn’t know it. Or until now, you didn’t even know about it. Optimizely is used for A/B testing on tons of sites that you visit, from to A/B testing is done to improve sites and provide a better user experience for people like you. And 99.999% of the time you don’t notice it because it is making your life better. Only in this rare occasion is it bothering you. (And it’s because of your network)

How The Bookmarklet Works

The bookmarklet issues some instructions, coded into javascript, to the browser.

javascript:(function(){window.location += '?optimizely_opt_out=true'}())

This basically says the following:

“Here comes a javascript function”


“Take the current URL (aka window.location) and append to it the parameter to opt out of Optimizely.” This is explained further on

window.location += '?optimizely_opt_out=true'

“Do these instructions! When the URL is changed, the browser reloads the page with the opt out parameter. This tells Optimizely that no tests should be run on the page and should not load any additional images or information on to the page.” (And you won’t have to wait for it)


I hope this works out for you. Just remember, you don’t hate Optimizely, you hate slow internet connections!

Scale Optimizely Testing with Google Tag Manager

You already know that Google Tag Manager is an incredibly powerful tool but you may not know that it can literally do anything. In fact, Google Tag Manager made me pancakes this morning. Not really, but a man can dream.

Google Tag Manager is comprised of three components: Tags (the things that do stuff with data), Triggers (formerly Rules, the things that decide when/if stuff is done), and Variables (formerly Macros, the things that express the data). This post is one post of many that shows that, thanks to the Custom HTML Tag, Google Tag Manager can do virtually anything.

Custom HTML Tags let you place any HTML, CSS, or Javascript on to the page that you might want. This could be anything from a tracking pixel, to CSS rules similar to Optimizely’s global CSS insert, to JavaScript AJAX commands to communicate with another API like Google Analytics, Lytics or if you must, SiteCatalyst. So when we say Google Tag Manager can do anything, we mean it. But that’s just because Javascript can do anything.

On Page Data Collection with Google Tag Manager

That being said, when we approach any on-page data collection problem, the question boils down to what is available and what needs to be passed on? To solve the problem simply clarify those two variables and use Google Tag Manager to draw the line between input and output.

Optimizley Goal Tracking is an excellent example of this. The input is pretty clear. We want to measure specific actions (most often clicks) that users might take or experience that will give us insight into the effect that our experiment is having. Aside from pageview tracking, output is less understood.

At a high level, we know what we want to see in terms of outputs: lines on a graph, hopefully with our new variation showing an improvement on the original. But how does it get there? While you can easily attach event triggers to clicks within the Optimizely interface. There are other events like Form Submit Events, YouTube Video Events , and Scroll Depth Events that are not quite as easy to capture.

This is where Custom Events and Optimizely’s Javascript API come in. At a basic level, whenever a Optimizley Goal happens, it is pushed into a queue of all the Goals that may have or may yet happen on the page. This queue of events are sent to Optimizely’s servers using Javascript AJAX (Asynchronous JavaScript and XML) when the Javascript commands can be executed. (This is much like how the  Google Tag Manager Data Layer works.)

At the Javascript code level, this is how it looks when a Goal is pushed onto the queue.

Optimizely Event Javascript

* Now is a good time to note, that Optimizely does not differentiate between Click Events and Custom Events. They are all Custom Events at the code level. The only thing that differentiates Event Goals is their names. (This is what you see when you click “Advanced”in the Goal setup process.) That is also what is used in the above code for “eventName”.

So now that we have a pretty good idea about what our output should be, it’s time to draw the line between input and output with Google Tag Manager.

Optimizely Custom Event Goal Setup

After a few Optimizely test implementations I came to realize I was repeating myself and I am a HUGE D.R.Y. principal person. With each implementation I found myself in the experiment setup clicking on an element to track and going through the process of making sure that this element actually tracked as expected. The problem was that every time I would setup these Goals, I would say to myself, “we are already tracking this with Google Analytics using Google Tag Manager.” So this is how I came up with this (fairly) universal method for tracking Optimizely Event Goals.

With Google Tag Manager, we specify triggers to determine when a Google Analytics Event is fired. This trigger also signals when Optimizely Event Goal actions take place. So the light went on and I decided to make both things happen at the same time.

Tracking Optimizely Event Goals With GTM

As I mentioned before, Google Tag Manager relies on “events” being pushed to the data layer similar to Optimizely Custom Event Tracking. Google Tag Manager’s syntax looks like this:

dataLayer push code

Where the “event” value, in this case: “customizeCar”, is used to trigger the firing of GTM tags. With each push to the dataLayer, additional attributes can also be specified to associate with that event. (This makes GTM much more scalable to use for multiple tag types. Also, now is a good time to read the documentation on this.)

Optimizely, on the other hand, sends a single event name for each goal. (Queue light bulb) We can just use the dataLayer event value from GTM for Optimizely Goal Events!

Configuring GTM Custom HTML Tags

You will need two things to do this: a Data Layer Variable to get the value of the dataLayer event and a, you guessed it, Custom HTML tag to pass the event to Optimizely.

GTM MenuData Layer Event Name Variable

GTM already provides a {{event}} auto-event variable but this is not what we are looking for. The Auto-Event Variable aka: {{event}} is used for listening for events and triggering tags but it won’t return the value of the current dataLayer “event” variable. We will need to make a variable to do this. Our new varialble will look like this:

Universal Optimizely Custom Event Tag with Goal Tag Manager

To send the event to Optimizely we will need a Custom HTML tag to run a little JavasScript script to interact with the Optimizely Javascript API and send the Custom Event Goals.

GTM Custom HTML Tag

Trigger the Custom Event Goal

This is where the logic happens! Decide which dataLayer auto event variable you would like to send to Optimzely as Custom Event Goals and set them up as triggers, as shown below. Because this trigger is (fairly) universal, it can be setup with multiple custom event triggers (shown below) as long as the dataLayer event names are unique.

GTM Customization

So that (fairly) universal tag works best when you are passing in data layer events that have unique names. Putting in the planning up front can really pay off down the road. We can apply the same idea to a few other metrics that you might have considered while setting up Optimizely like Form Submit Events, YouTube Video Events , and Scroll Depth Events.

Form Submit Custom Event Goal

The Custom HTML tag will look like this:

The Trigger will look like this – be sure to specify your form by element ID, Class or maybe data attributes. This is what the tag would look like if it had a distinctive element ID:

GTM Custom Form Event

Instead of setting it all up, download and merge this container including tag, variables and triggers here. [Instructions]

YouTube Video Custom Event Goals

If you are doing a test that involves optimizing a video, you want to track video plays with Optimizely.

The Custom HTML tag will look like this:

GTM Custom YouTube Event

This one is a little more complex so check out this explanation, or download and merge the complete container here[Instructions]

Page Scroll Depth Custom Event Goals

You might use this as a negative goal. The Custom HTML tag will look like this:

GTM Custom Scroll Event

This one is a little more complex so check out this explanation, or download and merge this container here[Instructions]

I hope all this offers an idea of the flexibility and limitless power of Google Tag Manager and answers the question, can I track that? Just remember, Optimizely is a great testing platform but Google Analytics is a great web analytics platform. If you need help with either, let us know. This is what we do and we love it.

Automate Optimizely Reports With the Results API

“Report automation” is my favorite two-word combo besides “free pizza.” And because of the nature of the testing and optimization game, and the speed it happens (in comparison to something like SEO), reporting can can pile up rather quickly. This is why I was as happy as [see picture below] when Optimizely recently released a test result endpoint from their REST API. To celebrate, I hid in my basement for hours on end and coded an Optimizely + Google Spreadsheet Report Automator that makes it easy to send email reports and import data directly into Google Spreadsheets.

Report Automation Greatness

A REST API, for those of you who haven’t fallen in love with HTTP yet, is essentially a menu of available data that you can request from a service, like Optimizely, Google Analytics, or Moz, based on the service’s URL that you request. (I borrowed that explanation from this great explanation of REST API’s on Quora.)

The Optimizely Results API

The Optimizely Results REST API makes available all the data about your Projects, Experiments, Experiments’ Variations, Goals, and Visitor Segments. If you’re really ambitious you can use the service to create, update, and delete experiments. For me, and hopefully you since you are reading this, the most useful part of the API is the Results endpoint. When you request the Results endpoint, the Optimizely API returns a list of all possible combinations of Goals and Variations. So if you have two variations: ‘Original’ and ‘Variation #1’ and three goals: ‘Engagement’, ‘Users Getting Totally Stoked’, and ‘Revenue,’ the API will return a list of six objects that describe how each variation performed for its corresponding goal.

I thought this was an interesting way of doing this but the awesome @OptimizelyDevs tell me that this is how it must be done in order to keep the service truly RESTful. (See: super-geek read about REST)

Automated Reports > Free Pizza

Back to delicious automation… I started automating reports for myself and team members as soon as I found out that the results endpoint was available and, ever since then, my life has been better. If you think about it, making data more available to your team is going to have two awesome results:

  • Less time wrangling data means more time analyzing and ideating!
  • Promotes an open culture of testing by giving everybody a stronger connection to the experiments and results.

How to Automate Your Optimizely Reporting

With the Results endpoint, there are a number of ways you could set up experiment reporting, like notifications when experiment goals have reached thresholds, notifications when experiments start or end, or time-based reporting to keep your team up-to-date. I tried to make this as broadly accessible to as many experiment driven optimizers as possible so I used the Optizely’s generic export format that you get when you share an experiment’s results. You can either email this to a list of emails or print it to a spread sheet. I made the assumption that you would only want to report on active experiments so that’s what this does. Please comment below to suggest changes. Let’s make this awesome!

Step 1: Enter Your API Token

Go to the Optimizely + Google Spreadsheet Report Automator and make a copy.

To get your Optimizely API token, go to, and click “Generate.” Copy the active token into the Optimizely API Token box then go to the Optimizely Reports menu and click “Test API.”


Optimizely Report Automation API Key

This should bring up the following. Please comment if it doesn’t.

Optimizely Report Success

Step 2: Send Email Reports

Enter a list of emails and click “Email Reports” in the Optimizely Reports dropdown. Wait a tick and check your inbox. You have become a reporting spam master!    

Step 3: Auto-create Spreadsheet Reports

Click the Spreadsheet Reports menu item, wait for some HTTP calls and  watch the sheets populate.

Step 4: Set Triggers and Automate Everything!

To set up a time-based trigger, from the spreadsheet click “Tools” > “Script editor…” to open the script editor.

Optimizely Report Menu

Don’t worry, there’s no need to touch the code. In the code editor window click “Resources” > “Current Project’s Triggers.”

Optimizely Report Google Apps Script

Then setup up your time-based trigger for the reporting method that you want.

Optimizely Report Triggers

Test Like Crazy! Report Like a Sane Person!

I hope this works out for you. Please comment with any issues that you might face. If you think this could really be improved. Let me know. Let’s make something great!