We have a custom Google Analytics plugin that will be sending commands to track custom pageviews and log events. Here's a simplified repro of our scenario:
// Version 1: only works with analytics.js, not with GTM
function GaPlugin(tracker, config) {
// Simplified for SO, we actually use the config argument
// to track more interesting pages and events...
ga(tracker.get('name') + ".send", "pageview", "/virtual/page/view");
}
var ga = window[window["GoogleAnalyticsObject"] || "ga"];
if (typeof ga == "function") {
ga("provide", "myAnalytics", GaPlugin);
ga("require", "myAnalytics", { /* omitted for simplicity */ });
}
This works fine if analytics.js
is included directly on the page. However, we're now including universal analytics on the page using the Google Tag Manager. Thus we ran into the dreaded error...
Command ignored. Unknown target: undefined
...as seen in the Google Analytics debugging Chrome plugin when the require
command is being executed.
This question and this blogpost imply the need to set a tracker name (in GTM, using: Edit Tag => More Settings => Advanced Configuration => Set Tracker Name checkbox) but the tooltip says "Use of named trackers is highly discouraged in GTM". So instead I changed things to this:
// Version 2: crashes with GTM because ga is loaded after this code
function GaPlugin(tracker, config) {
// Simplified for SO, we actually use the config argument
// to track more interesting pages and events...
ga(tracker.get('name') + ".send", "pageview", "/virtual/page/view");
}
var ga = window[window["GoogleAnalyticsObject"] || "ga"];
if (typeof ga == "function") {
ga("provide", "myAnalytics", GaPlugin);
ga(ga.getAll()[0].get("name") + ".require", "myAnalytics", { });
}
But now I'm met with an error because ga
is undefined
when the above executes, because GTM will load universal analytics asynchronously, where I want to run my code to bootstrap the plugin right away. This also means I cannot place a callback on the ga
command queue, because again: it doesn't exist yet.
In essence, the order of things (I think) is now:
- The GTM snippet starts loading (async).
- My own javascript code runs.
- GTM will start loading analytics (async).
- Analytics is loaded and ready to be used.
The only workaround I could think of was this:
// Version 3: ugly workaround...
function GaPlugin(tracker, config) {
// Simplified for SO, we actually use the config argument
// to track more interesting pages and events...
ga(tracker.get('name') + ".send", "pageview", "/virtual/page/view");
}
var interval = setInterval(function() {
var ga = window[window["GoogleAnalyticsObject"] || "ga"];
if (typeof ga == "function" && typeof ga.getAll == "function") {
ga("provide", "myAnalytics", GaPlugin);
ga(ga.getAll()[0].get("name") + ".require", "myAnalytics", { });
clearInterval(interval);
}
}, 250);
Isn't there a better way to do this? The GTM documentation nor the GA Plugins documentation seems to have any info on this.
As a footnote, I just realized it might also work if I mimic the tracking snippet by creating ga
as a command queue myself. But that also feels like a workaround, not a solution...