Google Tag Manager with AngularJS?

Christian THC picture Christian THC · Jan 28, 2014 · Viewed 25.1k times · Source

How do I use GTM with Angular?

I'm trying to fire a (virtual) pageview event when I load a new partial using this code:

dataLayer.push({
    'event' : 'pageview',
    'pageview' : $location.path(),
    'virtualUrl' : $location.path()
 });

But I don't see the event firing (I'm using the Google Analytics Chrome debug extension to view fired events).

Answer

Mike Causer picture Mike Causer · Jan 29, 2014

I find the Chrome extension unreliable. Simply run the global variable dataLayer in the console to print the array of events. One of the objects should be your pageview event.

Here is an example of how we are using it:

Note: we're not simply using $location.path(), instead everything in the url after the domain. Which includes the .search() & .hash().

$location in the Angular docs

modules/analytic.js

(function(window, angular) {
    'use strict';
    angular.module('Analytic.module', ['Analytic.services']).
        run(function($rootScope, $window, $location, GoogleTagManager) {
            $rootScope.$on('$viewContentLoaded', function() {
                var path= $location.path(),
                    absUrl = $location.absUrl(),
                    virtualUrl = absUrl.substring(absUrl.indexOf(path));
                GoogleTagManager.push({ event: 'virtualPageView', virtualUrl: virtualUrl });
            });
        });
})(window, window.angular);

services/analytic.js

(function() {
    angular.module('Analytic.services', []).
        service('GoogleTagManager', function($window) {
            this.push = function(data) {
                try {
                    $window.dataLayer.push(data);
                } catch (e) {}
            };
        });
})();

In GTM

You'll need {{virtualUrl}} and {{event}} Macros which listen for the dataLayer variables of the same name.

You'll need a Google Analytics Event Tracking Tag with a Firing Rule which triggers when {{event}} equals 'virtualPageView'. Make sure you remove the default 'All Pages' Rule which makes it run on every page load. Instead, you want it to run when you dataLayer.push() the event, which may happen multiple times per page refresh.

The Tag should be configured with:

  1. Track Type == 'Page View'
  2. More Settings > Basic Configuration > Virtual Page Path == '{{virtualUrl}}'