This is an update of the article “Add Optimizely with Universal Analytics via Tag Manager” previously from our organization. Some things have changed with improvements to code from both Optimizely and Google Tag Manager (GTM). Some issues remain and we’ll expand on the issues.
First, let’s cover some basics of how site testing tools like Optimizely work with your site content. The tools work with your site code to swap out content elements. You identify the elements and Optimizely makes that dynamic content.
For example, let’s say your site has a button element:
Defined by this html and CSS:
<div class=pink>
<a href="/solution.html" class="solid-button">Find a solution</a>
In the testing software you can redefine the specific element to be a gray box with pink text with text “Learn more”. On your site your button is now:
This is the first step. Optimizely then uses tracking code to tell what change has occurred and if that improved or degraded site performance. We’ll cover implementing Optimizely conversion tracking in a future blog. This article is covering how to install the base code.
The first issue is to swap out the page element Optimizely needs to be ready as soon as possible in the page load to prevent the site visitor from seeing the swap. GTM loads late in the page process, as is appropriate for an analytics tag but not always optimal for dynamic content swap.
If the content swap happens after the original content is loaded the visitor will see a flash or flicker during the change. The default location for Optimizely code is to manually place it at the start of the head section so it has a better chance of swapping content before the content is visible. But there are advantages to implementing the code in GTM to gain control over when and if the Optimizely tag is used. It may even be you cannot place it in the page code so the existing GTM structure is the only way to get the code on your site.
Note, Some other tag managers like Adobe DTM, Tealium, and Ensighten have part or all of the tag code load early in the <head> section and allow having some code load synchronously (as soon as the tag code loads). GTM loads asynchronously, it runs depending on timing of other page code so the load time and position are not fixed.
We can reduce element flicker in GTM by optimizing when the main Optimizely code runs. But because of GTM’s asynchronous operation we will still have risk of flash, particularly before GTMs support .js file is loaded into the browser’s cache.
First make sure your GTM tag is placed early in your page code - just after the initial <body> tag. The GTM tag loads its first files when it can which is usually early in the page load process. Placing the GTM tag at the start of the page code lets GTM start its process earlier, even if the Google Analytics tracking hit is not sent until after the page had loaded.
A simple script in the page code directly places Optimizely.
<script type="text/javascript" src="//cdn.optimizely.com/js/12345678.js"></script>
where the .js name is the Optimizely account ID.
To place this script using GTM create a Custom HTML Tag containing the script.
This will inject the script into the page code when this tag fires. The second script will put a value into the dataLayer object that GTM can use to tell that the tag is loaded.
One other tag option is available for pushing the Optimizely tag as soon as possible. In the Advanced Settings is “Tag firing priority”
A higher number (tags without this value are set to priority zero) pushes the tag to earlier in the GTM queue. Enter a number high enough to push the Optimizely tag before other HTML or Page View tags. “1” will do it if you are not using this feature on other tags but let’s go ahead and set it to “5”.
The fireing point, or trigger, is where you tell GTM when to run the tag code. Create a Custom Event Trigger. The event we are going to use one of the built-in gtm events. If you enter gtm into the trigger Event name box GTM will give you a list of those type of events.
· gtm.js – when the GTM code is first available, usually when the main GTM .js file is loaded. This is the one we want, as it is the earliest event.
· gtm.dom – when the page DOM has loaded, the page structure is loaded but not necessarily all the page content. The GA page tracking tag often fires near this event.
· gtm.load – when the window is loaded, usually when the content is loaded, but some asynchronous content may still be in process.
· gtm.click – when a click event (link, form submit button, etc.) occurs after the page is loaded. We may use this to track conversion events but it is not relevant to the initial load.
Since we want the Optimizely tag to load as soon as possible we will use gtm.js as our trigger point. Depending on the page structure there may not be much difference between gtm.js and gtm.dom. If you have intermittent timing issues where the Optimizely code does not load try changing the trigger event to gtm.dom.
At this point you can choose other firing conditions to reduce where the Optimizely loads. For example, on a specific URL section.
While this is one of the main advantages to using GTM, be very careful with trigger conditions! Conditions are variables that have to be evaluated before the tag will fire. Additional conditions can delay the tag firing which can increase the risk of flickering. If the variable requires something from the page content to resolve, GTM will wait until that information is available before firing. Unless you have requirements to only run Optimizely on certain URL based sections or a condition resolved early in the page load process choose the “All Custom Events” selection with no conditions is the fastest.
Now you should have the Optimizely page code loading. This allows Optimizely to content swap with minimal flicker. Zero flicker is not guaranteed, this is the best we can do in the GTM asynchronous structure.
When Optimizely is active it creates a global variable object called “optimizely”. Thank you Optimizely for selecting a unique name. There are way too many global objects with names like “s”. To check if the code has loaded we’ll look for this object.
Open the browser’s Developer Tools (hit control or right click on the page and select “Inspect” on most browsers). Go to the Console. At the prompt enter “typeof optimizely” (without quotes). It should return “object”. If you get “undefined” the code has not loaded.
There is one other method I have seen mentioned for preventing test content swap flicker. This is done CMS side where you have the CMS delay loading all the page content until it detects the testing object, the event:optimizely_loaded, or a two second fallback. While this would work, many site developers will not agree to put a delay into page load for a non-primary content function. But it is an option if the test code must go in GTM and you want to prevent any flicker.
By using the methods here, you should be able to reduce content swap flicker while loading and controlling Optimizely from GTM. In a future article we will discuss implementing the conversion/success tracking portion in GTM.