The Google Optimize snippet for the container with ID GTM-... is not correctly installed on this page - google-analytics

I'm trying to use Google Optimise with Analytics installed by gtag.js and am getting errors in some parts of the Optimise UI but not others.
Here's what I've done:
Installed Google Analytics following the instructions "Set up Analytics tracking with gtag.js" (and confirmed it's working by using the Real-Time Preview).
Set up Google Analytics following the instructions "Deploy Optimize using Global Site Tag (gtag.js)"
Added the page-hiding snippet.
When I set up an experiment using the Chrome extension, Optimise appears to be running as Google expect - notice that there's no number shown by the exclamation mark icon in the screenshot below (there is if I remove the Optimise code), and clicking it says "no issues detected". (Also, the chrome extension's icon doesn't have any error symbol.)
However, if I then preview either the original or the variant (clicking the "screen" icon in Optimise), I get a javascript alert which says:
The Google Optimize snippet for the container with ID GTM-abcdef is not correctly installed on this page. To preview variants for this experiment, make sure the Google Optimize snippet is installed on any pages you want to test.
(I've replaced my actual container ID by "abcdef" in the above.)
And the Chrome extension icon also shows an error and a similar message when clicked (I've blacked out the experiment name here):
Here's my HTML <head> section (with IDs redacted):
I've compared the script from this with the example in "Deploy Optimize using Global Site Tag (gtag.js)" and they appear identical except that my code contains real IDs:
<head>
<meta charset="UTF-8">
<!-- Page hiding snippet (recommended) -->
<style>.async-hide { opacity: 0 !important} </style>
<script>(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;h.start=1*new Date;
h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};
(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);h.timeout=c;
})(window,document.documentElement,'async-hide','dataLayer',4000,
{'GTM-zyxzyx':true});</script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-abcdef"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-abcdef', { 'optimize_id': 'GTM-zyxzyx'});
</script>
<title></title>
</head>
I've tried this against a site running locally (on Flask's webserver, port 5000) and against a site deployed onto Heroku, and behaviour is the same in both instances.
I've also tried removing the page-hiding snippet code, but that didn't help.
I've also tried actually running the experiment but always saw the original variant even when setting the alternative one to have 100% traffic, so it's not working there. (I only tried this against local site, haven't tried against the Heroku instance.)
It's worth noting that there's this line in the GA code:
function gtag(){dataLayer.push(arguments);}
I've seen it online in that form and with the semi-colon at the end:
function gtag(){dataLayer.push(arguments)};
I've tried both without any effect.
What am I doing wrong here?

I don't know if this is correct, but should the hiding snippet be using the ID UA-abcdef?
If you’re using Google Tag Manager to deploy Optimize, populate the
page-hiding snippet with your Tag Manager container ID, not your
Optimize container ID. Learn more about using Optimize with a
tag-management system (from here: https://support.google.com/optimize/answer/7100284?hl=en)
I'm not sure whether deploying the code this way is classed as deploying Optimize with Google Tag Manager though. What do others think?

Related

Using Google Analytics' global site tag (gtag.js) to measure Scroll Depth

I have currently implemented Google Analytics on a web property of mine via adding the following Global site tag (gtag.js) on all web pages:
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXXX-Y"></script>
<input id="user_id_val" type="hidden" name="user_id" value="{{ user_id }}">
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
var user_id = document.getElementById("user_id_val").value;
if (user_id)
{
gtag('set', {'user_id': user_id}); // Set the user ID using signed-in user_id.
gtag('config', 'UA-XXXXXXXXX-Y');
}
</script>
Note that this snippet has been enriched with user_id to enable session unification.
Next, I need to implement Scroll Depth for my web property.
How do I do that via the Global site tag (gtag.js) I am already using? I cannot find any documentation for the same. Can an industry expert give an illustrative example of how that could be done? And if it cannot be done, it is alright to simply point that out.
Postface:
Normally, Scroll Depth is measured via adding Google Tag Manager to the project. That is well-documented.
So why am I not following the recommended route of adding the Google Tag Manager snippet to measure Scroll Depth? Why am I trying to do it via Global site tag (gtag.js)? Because:
I have read that one can indeed deploy tags via Global site tag (gtag.js) as well. This official doc page explains that this is possible. So what I am attempting makes sense in theory.
I already have the Global site tag (gtag.js) injected all over my site. If I can piggy back on that to enable Scroll Depth measurement, then that is my preferred solution.
My alternative would be to replace the already configured Global site tag (gtag.js) with the Google Tag Manager snippet.
But that introduces the additional headache of how to enable session unification in GTM (another requirement of mine), which I configured with gtag.js. This transition could also break my GA. Or create duplicated effort.
Since that could overall be a messy situation needing a lot of troubleshooting, I am firstly exploring ways of just using the Global site tag (gtag.js) to solve my Scroll Depth measurement issue. Hence this question.

Solving configuration mismatch between Google Analytics and Google Optimize?

So I'm using Google Analytics, Google Optimize, and Google Tag Manager. I also feel that I may be losing my mind.
For performance reasons, we don't want to add the google optimize script through GTM. We want to hard-code it. But every time I try that, the installation doesn't work. Specifically, when I click "Run Diagnostics" on the google optimize setup page, I get an error that says
All Analytics tracking code on the page must have the same tracker configuration settings. [...] The following tracker configuration properties do not have the same configurations: alwaysSendReferrer.
So I go into my handy Analytics debugger, find the alwaysSendReferrer property, and note that it's set to true. Great. I edit the config object that i'm passing to the google optimize init script, and I add alwaysSendReferrer: true. So far so good. Except... I get the same error.
I thought maybe something was wrong with our analytics setup, so I got rid of the hardcoded google optimize script and instead included it via the Google Optimize GTM tag -- which, unexpectedly, worked perfectly. I thought "Okay i'll just find the script that GTM is adding and copy/paste it into the codebase" but of course it's minified within an inch of its life, and untangling that javascript from the rest of the tags would be a whole other endeavor.
I have access to a {{Default UA Settings}} variable in GTM, and google's documentation would really like me to just pass that object to the official "Google Optimize" tag in GTM. That works (I've tested it), but as mentioned, we don't want to do that.
If anyone knows what the Google Optimize config object should look like, that would help me massively.
Right now mine looks like this (with identifying details removed)
dataLayer.push(['config', 'UA-12345', {
'optimize_id': 'GTM-55555',
'linker': { 'domains': ['mywebsite.com <http://mywebsite.com>'] },
'alwaysSendReferrer': true
});
I've tried false, "true", 1, and basically everything else I can think of (I'm quite confident that Google Analytics has this property set to true on our site) -- my only guess is that maybe I'm setting the value in the wrong place and google optimize isn't seeing it. Help?
I know the feeling of losing your mind trying to read through Google documentation!
This is the code I use on pages I wish to run Optimize experiments on:
<head>
...
<!-- 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-PRMQXXX');</script> <!-- End Google Tag Manager -->
<!-- Page-hiding snippet (recommended) -->
<style>.async-hide { opacity: 0 !important} </style>
<script>(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;h.start=1*new Date;
h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};
(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);h.timeout=c;
})(window,document.documentElement,'async-hide','dataLayer',4000,
{'GTM-KL7XXXX':true});</script>
<!-- Modified 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-99999999-1', 'auto');
ga('require', 'GTM-KL7XXXX');
ga('send', 'pageview');
</script>
...
</head>
Where:
GTM-PRMQXXX is the Google Tag Manager container id
GTM-KL7XXXX is the Google Optimize container id, and
UA-99999999-1 is my Google Analytics id
Note that you need to remove your usual GA script once you add the scripts above.
I hope this helps you!

Google Optimize not triggering when running on localhost

I am trying to get Google Optimize experiment data in JavaScript, by following these instructions. But I get no callback and I can't see anything happening in the debugger either.
The linked instructions use the gtag way of configuring GA, so I have set up gtag according to https://developers.google.com/gtagjs/devguide/snippet, and configured Optimize according to https://support.google.com/optimize/answer/7513085?hl=en with Method 1: Install Optimize with the global site tag (gtag.js).
I want to show the exact code I am using, but since I am doing it in React with Next.js Server Side Rendering, the original code has some extra stuff compared to plain HTML+JS. The source looks like this:
require("dotenv").config()
import React from "react"
import Document, { Head, Main, NextScript } from "next/document"
export default class extends Document {
render() {
return (
<html>
<Head>
<script async src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GA_TRACKING_ID}`}/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', '${process.env.GA_TRACKING_ID}', { optimize_id: '${process.env.OPTIMIZE_ID}'});
console.log('GA setup done: ${process.env.GA_TRACKING_ID} + ${process.env.OPTIMIZE_ID}');
gtag('event', 'optimize.callback', {
name: '${process.env.EXPERIMENT_ID}',
callback: o => console.log(o)
});
`
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
This code produces a result page that starts Analytics and tracks a pageView just like it should, and when I do "RUN DIAGNOSTICS" in the Google Optimize console it opens the page, checks the JavaScript and reports:
Optimize is correctly installed
No major issues were detected while verifying the Optimize installation on this page.
I have also installed the Google Chrome Tag Assistant plug-in, and it reports that the Google Optimize tag is correctly installed.
I can see the following calls in the network log:
https://www.googletagmanager.com/gtag/js?id=UA-xxxxxx
https://www.google-analytics.com/analytics.js
https://www.google-analytics.com/gtm/js?id=GTM-xxxxxx&t=gtag_UA_xxxx&cid=nnn.nnn
I have also verified that the google_optimize global variable is created, and it has a .get() method. If I look (in the debugger network panel) at the http response of the https://www.google-analytics.com/gtm/js?... request I can actually see the Google Optimize experiments data with the correct Experiment embedded in the code.
So everything looks good, except for the fact that the optimize.callback event seems to be a complete no-op. It does not do anything at all. And I don't know how else to access the experiments data that I see in the http response in the debugger.
So I finally figured out what caused my struggles: I was running from a local NodeJS server, on the usual http://localhost:3000 url. Turns out Google Optimize will never trigger an experiment on http://localhost/... urls. The code wants a hostname part of the url that can be parsed according to a host.domain scheme.
In other words, there must be a dot in the hostname for Optimize to trigger an experiment.
For local testing, this can be fixed by creating a hostname alias such as localhost.domain for 127.0.0.1, and accessing the web page using this alias.
I found a way, which can achieve start google optimize experiment with localhost.
So, just use next settings for google optimize experiment and it will start successfully.

How can I set a (Google Analytics) Content Experiment (A/B test) with a singular URL?

I want to test whether a variant of my current homepage will perform better (reach a certain goal defined on GA), but I'm struggling to find a good solution.
Let's say the current version (Original) has sections A, B, C in that order. The other version (Variant), though, has sections in the order B, C, A. Note: the top navigation menu (linking to each section's anchor) must reflect this change.
I first considered Client-Side Experiments, which I have done in the past, but I'm worried those wouldn't look good when rendering the site: depending on loading speed, a Variant user would first see section A, and then they would see section A vanish (into the bottom of the page), while they could also notice the menu being changed.
I then considered the regular Experiment mode on Analytics, which asks me to determine two URLs to compare: the Original is my root path (e.g. http://mywebsite.xyz/) and the Variant would be something like http://mywebsite.xyz/home. But I can't orientate half of my users to this different URL - I want to test people who reach my homepage from wherever they may come.
I tried something through the Google Cloud App Engine: publishing two versions of my application, and splitting traffic 50/50 between both (cookie-based). When visiting the root path, one renders the Original, while the other renders the Variant version. Great. It works! But now Google Analytics has no idea which version it's tracking...
What I did: when the page first loads, I send an event with the version identifier as parameter, such as
ga('send', 'event', 'AB_Test', 'A');
// or
ga('send', 'event', 'AB_Test', 'B');
I suppose these would help me check the Events Flow and determine which version reaches more Event goals, but it's still not linked to an Experiment or its features.
Is there any better way to implement this? Am I missing something? It feels too complicated to do something that both the Cloud App Engine and the Analytics should help me achieve. (Thanks for reading, I know it's a huge text)
When I run this type of experiment, I typically try to leverage the API to determine the variation in the backend and then render the template appropriately.
For your current workaround, rather than sending events, I'd recommend instantiating the test on each server and manually setting the variant for each. See code below:
<!-- App 1 / Original -->
<script type="text/javascript" src="//www.google-analytics.com/cx/api.js?experiment=<EXPERIMENT ID>"></script>
<script type="text/javascript">
(function () {
cxApi.setChosenVariation(0);
}());
</script>
<!-- App 2 / Variant -->
<script type="text/javascript" src="//www.google-analytics.com/cx/api.js?experiment=<EXPERIMENT ID>"></script>
<script type="text/javascript">
(function () {
cxApi.setChosenVariation(1);
}());
</script>

Is ASP.NET (webforms) Incompatible with Google Website Optimizer Multivariate Testing?

I've been stuggling all morning trying to get a multivariate test going in google website optimizer.
I've copy and pasted the header/footer code into the pages, and setup a basic page section just to see that everything is working.
When I try to validate the code its failing saying
"No sections detected on test page
TestSectionName - Unexpected or missing characters - Line: 422 Expected: </noscript>"
The silly thing is that the output is clearly there (I have used an asp literal to get around the asymetric noscript tag) and can clearly see it in the source as follows:
<script>utmx_section("TestSectionName")</script><h1>Buy This Product!</h1></noscript>
I've already tried disabling/removing the existing google analytics code in the site on the off chance that was conflicting with it with no luck.
I think there might be some incompatibility with the asp.net framework and this WSO framework. I was able to use exactly the same code saved into a raw html file with no asp.net/page content and have it validate ok.
e.g.
<html><head></head><body>
<!-- Google Website Optimizer Control Script -->
<script>
function utmx_section(){}function utmx(){}
(function(){var k='xxxxx',d=document,l=d.location,c=d.cookie;function f(n){
if(c){var i=c.indexOf(n+'=');if(i>-1){var j=c.indexOf(';',i);return c.substring(i+n.
length+1,j<0?c.length:j)}}}var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;
d.write('<sc'+'ript src="'+
'http'+(l.protocol=='https:'?'s://ssl':'://www')+'.google-analytics.com'
+'/siteopt.js?v=1&utmxkey='+k+'&utmx='+(x?x:'')+'&utmxx='+(xx?xx:'')+'&utmxtime='
+new Date().valueOf()+(h?'&utmxhash='+escape(h.substr(1)):'')+
'" type="text/javascript" charset="utf-8"></sc'+'ript>')})();
</script>
<!-- End of Google Website Optimizer Control Script -->
<script>utmx_section("TestSectionName")</script><h1>Buy This Product!</h1></noscript>
<!-- Google Website Optimizer Tracking Script -->
<script type="text/javascript">
if(typeof(_gat)!='object')document.write('<sc'+'ript src="http'+
(document.location.protocol=='https:'?'s://ssl':'://www')+
'.google-analytics.com/ga.js"></sc'+'ript>')</script>
<script type="text/javascript">
try {
var gwoTracker=_gat._getTracker("UA-xxxxx-1");
gwoTracker._trackPageview("/xxxxx/test");
}catch(err){}</script>
<!-- End of Google Website Optimizer Tracking Script -->
</body>
</html>
After all of this I am wondering if there is
a) anyone out there using asp.net with multivariate testing successfully
b) a known incompatibility with something in asp.net
c) known "donts" when it comes to coding with WSO multivariate testing
d) something really obvious I am missing?
I have used Google Website Optimizer multivariate tests on an ASP.NET website without any problem.
Have you tried putting </noscript> on its own line? I think I always put it on a blank line after the default section.

Resources