I\'m setting up a new app using AngularJS as the frontend. Everything on the client side is done with HTML5 pushstate and I\'d like to be able to track my page views in Goog
I've created a simple example on github using the above approach.
https://github.com/isamuelson/angularjs-googleanalytics
I found the gtag()
function worked, instead of the ga()
function.
In the index.html file, within the <head>
section:
<script async src="https://www.googletagmanager.com/gtag/js?id=TrackingId"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'TrackingId');
</script>
In the AngularJS code:
app.run(function ($rootScope, $location) {
$rootScope.$on('$routeChangeSuccess', function() {
gtag('config', 'TrackingId', {'page_path': $location.path()});
});
});
Replace TrackingId
with your own Tracking Id.
Merging the answers by wynnwu and dpineda was what worked for me.
angular.module('app', [])
.run(['$rootScope', '$location', '$window',
function($rootScope, $location, $window) {
$rootScope.$on('$routeChangeSuccess',
function(event) {
if (!$window.ga) {
return;
}
$window.ga('send', 'pageview', {
page: $location.path()
});
});
}
]);
Setting the third parameter as an object (instead of just $location.path()) and using $routeChangeSuccess instead of $stateChangeSuccess did the trick.
Hope this helps.
Use GA 'set' to ensure routes are picked up for Google realtime analytics. Otherwise subsequent calls to GA will not show in the realtime panel.
$scope.$on('$routeChangeSuccess', function() {
$window.ga('set', 'page', $location.url());
$window.ga('send', 'pageview');
});
Google strongly advises this approach generally instead of passing a 3rd param in 'send'. https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
Merging even more with Pedro Lopez's answer,
I added this to my ngGoogleAnalytis module(which I reuse in many apps):
var base = $('base').attr('href').replace(/\/$/, "");
in this case, I have a tag in my index link:
<base href="/store/">
it's useful when using html5 mode on angular.js v1.3
(remove the replace() function call if your base tag doesn't finish with a slash /)
angular.module("ngGoogleAnalytics", []).run(['$rootScope', '$location', '$window',
function($rootScope, $location, $window) {
$rootScope.$on('$routeChangeSuccess',
function(event) {
if (!$window.ga) { return; }
var base = $('base').attr('href').replace(/\/$/, "");
$window.ga('send', 'pageview', {
page: base + $location.path()
});
}
);
}
]);
If someone wants to implement using directives then, identify (or create) a div in the index.html (just under the body tag, or at same DOM level)
<div class="google-analytics"/>
and then add the following code in the directive
myApp.directive('googleAnalytics', function ( $location, $window ) {
return {
scope: true,
link: function (scope) {
scope.$on( '$routeChangeSuccess', function () {
$window._gaq.push(['_trackPageview', $location.path()]);
});
}
};
});