Installing Google Optimize the Right Way with GA and GTM

Installing Google Optimize the Right Way with GA and GTM

Are you ready to get started with Google Optimize? After setting up your Optimize account, the next step is to install the provided code snippet on your website. It sounds simple, but in our experience many people get stuck at this stage due to the complexity of integrating with their other analytics products—specifically Google Analytics and Google Tag Manager.

If you are already using GA and GTM, you will need to ensure that your Optimize code peacefully coexists with your current implementation. The placement and configuration of the Optimize page-hiding code, GA snippet, GTM container, and data layer all matter. Placing code in the wrong order or using the wrong configuration settings can break your GA tracking, prevent tags from firing through GTM, invalidate your A/B tests, or at worst disable your entire web analytics implementation.

Luckily, we’re here to help! We have put together a step-by-step guide to help you get Optimize up and running alongside your existing GA and GTM implementation.

Combining Google Optimize, GA, & GTM Code Snippets

At this point, we’re assuming you have already created an Optimize account and linked it to your Google Analytics property. If you haven’t, follow the steps in this Help Centre article first. Once your account is created and linked, you’ll be ready to proceed with the steps below. We’ll go through each piece of code in the order it should appear on the page. A full code example is included at the end.

1. Data Layer Initialization

If you are explicitly initializing your data layer for GTM, this code needs to come first. This ensures that your data layer variables are available for use in experiment targeting in Optimize. Google recommends placing the code as high as possible in the HEAD section of the page, but after the <meta charset> declaration.

<head>
<meta charset="utf-8">
<script>
window.dataLayer = window.dataLayer || [];
//If necessary, push info into data layer here with dataLayer.push()
</script>

2. Page-Hiding Snippet

The page-hiding snippet helps prevent page flicker when loading experiment variants, providing a better end-user experience. For more information about how page-hiding works, see this Help Centre article. The page-hiding snippet must be configured with your Optimize container ID.

Note that both Optimize and GTM container IDs begin with “GTM-“. Replace GTM-XXXXXX in the code below with your Optimize Container ID.

<!-- Page hiding snippet for Optimize -->
<style>.async-hide { opacity: 0 !important} </style>
<script>
(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;
h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};
(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);
})(window,document.documentElement,'async-hide','dataLayer',4000,{'GTM-XXXXXX':true});
</script>

3. Analytics-Optimize Snippet

The Analytics-Optimize snippet is a modified version of a base GA analytics.js tracking snippet. There is an added “require” line that loads the Optimize plugin, and the usual “pageview” function is removed (This assumes that you have a GA pageview tag firing from GTM). This snippet is what actually loads Optimize.

Replace UA-YYYYYYY-Y with your GA Property ID, and replace GTM-XXXXXX with your Optimize Container ID.

If you have cross-domain tracking configured and the “allowLinker” field set to “true” in your GA tag in GTM, then you need to include {allowLinker : true} in the create function below. Also, ensure that your GA tag in GTM has the cookieDomain field set to “auto”.

<!-- Analytics tracking code with Optimize plugin -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-YYYYYYY-Y', 'auto', {allowLinker: true}); //Insert GA Property ID
ga('require', 'GTM-XXXXXX'); //Insert Optimize Container ID
</script>

4. GTM Container Snippet

This is the standard GTM container snippet for the HEAD section. Replace GTM-ZZZZZZ with your GTM Container ID.

Although it is possible to deploy Optimize through a tag in GTM, we do not recommend this approach as it will often result in significantly increased latency. The method detailed in this post does not require any configuration within GTM to enable Optimize.

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-ZZZZZZ');</script>
<!-- End Google Tag Manager -->

Example Implementation

When you put all the pieces together, you will have a combined code snippet for Optimize, GA, and GTM that looks like the following. Note that we have also shown the noscript snippet for GTM in the BODY, although it is not impacted by the Optimize implementation.

<head>
<meta charset="utf-8">
<script>
window.dataLayer = window.dataLayer || [];
</script>

<!-- Page hiding snippet for Optimize -->
<style>.async-hide { opacity: 0 !important} </style>
<script>
(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;
h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};
(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);
})(window,document.documentElement,'async-hide','dataLayer',4000,{'GTM-XXXXXX':true});
</script>

<!-- Analytics tracking code with Optimize plugin -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-YYYYYYY-Y', 'auto', {allowLinker: true}); //Insert GA Property ID
ga('require', 'GTM-XXXXXX'); //Insert Optimize Container ID
</script>

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-ZZZZZZ');</script>
<!-- End Google Tag Manager -->

//Other scripts and tags in HEAD
...
</head>

<body>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-ZZZZZZ"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
...

Still have questions? Let us know in the comments or get in touch. We would be happy to help you get started with Optimize testing and personalization.

By |2018-12-04T17:02:11-05:00June 14th, 2018|20 Comments
Categories: Google Optimize

20 Comments

  1. Clinton L Gorman July 3, 2018 at 12:12 pm - Reply

    Awesome tutorial! I got stuck adding Optimize via GTM, so this is a nice way to do it.

    I’ve already added my GA via GTM. So the Analytics-Optimize snippet does not replace the original Analytics code, correct? It’s added as a separate snippet?

    If this snippet does replace the GA code, would I need to modify the GA snippet inside my GTM dashboard?

    • Marc Soares July 4, 2018 at 9:15 am - Reply

      Hi Clinton,

      That’s correct, the Analytics-Optimize snippet does not replace your GA tag in GTM. As described in step 3, you should ensure that the allowLinker and cookieDomain values match between your GA tag in GTM and the Analytics-Optimize snippet.

      Marc

  2. Vinita July 23, 2018 at 5:46 am - Reply

    Hey Marc,

    Can you please tell how to implement google optimize snippet if we are using ga-lite script? Any help will be highly appreciated.

    • Marc Soares July 23, 2018 at 12:34 pm - Reply

      Hi Vinita,

      Is there a reason that you are not using the standard implementation of Google Analytics? Since ga-lite is an unsupported implementation, it may not support Google Optimize. You will have to contact the ga-lite creator to inquire about Optimize support.

      We recommend always using an officially-supported implementation of Google Analytics.

      Marc

  3. Ilana December 4, 2018 at 2:43 pm - Reply

    Everything about our implementation appears correct, however since implementing our bounce rate has fallen to basically zero, indicating that something is amiss. What about the Optimize implementation could have caused this?

    • Marc Soares December 4, 2018 at 5:10 pm - Reply

      Hi Ilana,

      Are you using GTM for your GA tracking? If so, make sure you do not have ga('send', 'pageview'); in your Analytics-Optimize snippet. Your code should look like what’s shown in Step 3 above.

      If your bounce rate fell to zero, it sounds like you have duplicate pageviews being sent to GA, which would be caused by leaving the pageview function in your code.

      Marc

  4. Will January 9, 2019 at 3:37 pm - Reply

    Is it actually necessary to initialize the dataLayer manually if I’m not doing targeting based on the dataLayer? GTM automatically initializes the dataLayer in its snippet.

    I guess it can’t hurt, but it seems redundant.

    • Marc Soares January 9, 2019 at 5:12 pm - Reply

      Hi Will,

      The data layer initialization is not required if you are not populating any variables in the data layer.

      Marc

  5. Amol Dhamale July 19, 2019 at 6:16 am - Reply

    Hey Marc,

    I have followed the steps but still getting an ‘Analytics configuration mismatch’ error in Tag Assistant.

    I have cross-domain tracking enabled in GTM. Everything has been set up as per your instructions but it is still showing the error.

    Please help!

    • Marc Soares July 19, 2019 at 9:33 am - Reply

      Hi Amol,

      Have you set the cookieDomain field to auto and the allowLinker field to true in your GA tag in GTM?

      If that doesn’t resolve the issue, you can use the installation diagnostics feature in Optimize to see exactly which field(s) are mismatched (https://support.google.com/optimize/answer/7577190?hl=en).

      Marc

  6. Alexa DeVoe August 12, 2019 at 11:13 am - Reply

    Hi, do you know if I can use the Optimize callback function and still use analytics.js and GTM for pageview and enhanced ecommerce?

    I couldn’t find any articles that show examples for the Optimze callback function unless you use gtag.js. We noticed that when testing gtag.js and using datalayer and GTM that it only works with a virtual pageview tag. So either I have the order of the my code wrong or something. I will try doing what you stated in your article and put the datalayer stuff first. Maybe that will resolve my issue.
    We are trying to upgrade to gtag.js and still use the dalayer for our enhanced ecommerce and custom dimensions…. — since I believe the only way to use the callback function with Optimize is by using gtag.js

    We tried contacting Google Support but they had no answers.

    • Marc Soares August 27, 2019 at 11:52 am - Reply

      Hi Alexa,

      Are you implementing an experiment callback as shown here? This method should still work as long as the callback code is placed after your dataLayer initialization, Analytics-Optimize, and GTM code. If you don’t have the dataLayer first, I suggest starting with that. Notice that the code shown at that link includes function gtag() {dataLayer.push(arguments)}, which defines the gtag function. So, you should be able to add the callback, even if you are using analytics.js to install Optimize.

      Marc

  7. Joquim August 27, 2019 at 4:15 am - Reply

    I’ve previously used Optimizely. I started using Google Optimize recently but am not able to see where I’d specify the Goal (eg. a lead that is redirected to a “thank you” page). With other services, this has been tracked with a Conversion Pixel.

    Does anyone know how that works with Google Optimize? Will I see this data on Analytics or am I missing something here?

    • Marc Soares August 27, 2019 at 11:57 am - Reply

      Hi Joquim,

      When you configure an experiment in Optimize, you will select objectives. The objectives can be selected from goals in the linked Google Analytics view or system-defined objectives in Optimize. You can also create custom objectives in Optimize. Refer to the following Help Centre article for more details on objectives: https://support.google.com/optimize/answer/7018998?hl=en

      Hope that helps!

      Marc

  8. Carlos September 24, 2019 at 2:27 pm - Reply

    What is the recommended way of installing Google Optimize? Is it through GTM or adding the optimize script directly on the site?

    • Marc Soares September 30, 2019 at 6:08 pm - Reply

      Hi Carlos,

      Google currently recommends installing Optimize in the same method as you run Google Analytics, either with gtag.js or GTM. So, if your GA tag is running through GTM, then you should install Optimize through GTM. See the Help Centre article here: https://support.google.com/optimize/answer/7513085

      Marc

  9. Victor Fagundo September 27, 2019 at 2:24 pm - Reply

    Hi Mark,

    I am wondering if this “analytics-optimize” method is still the most performant method now that we have GTAG and its new method of loading optimize:
    “gtag(‘config’, ‘UA-34592858-5’, { ‘optimize_id’: ‘GTM-KCQXJTB’});”

    Is there a coresponding “gtag-optimize” method of installing Optimize, or with the Gtag changes is installing via a Gtag-optimize method or analytics-optimize method essentially the same as deploying optimize via GTM.

    Key concerns are having optimize load & modify the dom as quickly as possible.
    Anti-flicker snippet would be used in either scneario

    • Marc Soares September 30, 2019 at 6:13 pm - Reply

      Hi Victor,

      Google currently recommends installing Optimize in the same method as you run Google Analytics, either with gtag.js or GTM. So, if your GA tag is running through GTM, then you should install Optimize through GTM. See the Help Hentre article here: https://support.google.com/optimize/answer/7513085

      Note that the “gtag-optimize” method you included in your comment will also automatically send a pageview to GA. So, if you use this method along with a GA tag in GTM, you would duplicate your pageviews.

      Whichever method you choose, you will get the best performance for Optimize by placing your code as high as possible in the HEAD of the page.

      Marc

  10. Eric B October 16, 2019 at 10:04 am - Reply

    Great article, Marc! We are concerned that no longer lazy loading/delaying some GTM tags within our container will reduce pagespeed performance/load times due to Optimize needing to fire immediately. Have you witnessed any hits on performance in this sense?

    • Marc Soares October 21, 2019 at 3:31 pm - Reply

      Hi Eric,

      We haven’t observed any noticeable impact on page performance due to Optimize. If your site is having performance issues that you suspect are related to other tags, I suggest reviewing the impact of your tags in GTM, particularly Custom HTML tags.

      Marc

Leave A Comment