I implemented analytics.js (new version) in my ASPX webapplication.
I got pageview working just fine, but events is very often not being send.
In my example, I tried pushing 3 different buttons, but only one of them fired the event.
I added an alert-box to each event, to verify that it actually is fired, and these all show.
This is my js, placed just before the </head>
(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', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-XXXXXXXX-1', {
'cookieDomain': 'none'
});
ga('send', 'pageview', {
'page': '/team/main',
'title': 'Logged in'
});
$(document).ready(function() {
$(".team_button").on("click", function() {
ga('send', 'event', 'button', 'click', 'Team select button', {
'page': '/team/'
})
});
$(".calendar_month_prev").on("click", function() {
ga('send', 'event', 'button', 'click', 'Calendar: Prev month', {
'page': '/team/'
})
});
$(".calendar_month_next").on("click", function() {
ga('send', 'event', 'button', 'click', 'Calendar: Next month', {
'page': '/team/'
})
});
$(".calendar_day_selected").on("click", function() {
ga('send', 'event', 'button', 'click', 'Calendar: Same day reload', {
'page': '/team/'
})
});
$(".calendar_day_active").on("click", function() {
ga('send', 'event', 'button', 'click', 'Calendar: Select day', {
'page': '/team/'
})
});
});
When a new page is being loaded, pending requests on the current page are canceled -- in this case the analytics tracking pixel request. 'async' is referring more to the loading of the analytics javascript code then the processing of analytics data.
With ga.js, a common approach is to stop propagation of the click event, send the event, and then delay for a small amount (150ms) before following the link.
With analytics.js, instead of a delay, you can use hitCallback
to run code after the analytics data has been sent.
See Setting the Hit Callback in the Google Analytics docs
Okay, here is how I fixed it, if anyone else has the same problem:
I made a function, to call the analytics tracking, where I delayed the page for just a fraction of a second:
function TrackEvent(link, category, action, label, page) {
try {
ga("send", "event", category, action, label, { 'page': page });
} catch (err) { consol.log(err); }
setTimeout(function () {
document.location.href = link.href;
}, 25);
}
Then, each of my onClick binds calls this function, like this:
$(document).ready(function () {
$(".calendar_month_prev").on("click",function(){ TrackEvent(this, 'button', 'click', 'Calendar: Prev month', '/team/main'); return false;});
$(".calendar_month_next").on("click",function(){ TrackEvent(this, 'button', 'click', 'Calendar: Next month', '/team/main'); return false;});
$(".calendar_day_active").on("click",function(){ TrackEvent(this, 'button', 'click', 'Calendar: Select day', '/team/main'); return false;});
});
One could probably just add this to the a href onClick, if this is preferred :)
I would suggest executing a dummy anchor click after successful event registration :
a.onclick = function(e){
var anchor = this;
_gaq.push(['_trackEvent', 'Category','event','label']);
_gaq.push(function() {
var a = document.createElement('a');
a.href = anchor.href;
a.target = anchor.target;
a.click();
});
return false;
}
Since push works as a queue, your event request will never be cancelled..
As pointed out by Mike, you should use a hit callback in this case. In addition, you also need to take into account that users may block Google Analytics using some privacy protection tool such as Ghostery, in which case the hit callback will never be executed. Therefore you need to implement this very carefully so that your site continues to work even for these users. The following article explains how to do this properly:
http://veithen.github.io/2015/01/24/outbound-link-tracking.html