angular-google-analytics
This service lets you integrate google analytics tracker in your AngularJS applications easily.
You can use basic functions, Analytics.trackEvent('video', 'play', 'django.mp4');
or more advanced e-commerce features like product tracking, promo codes, transactions...
Proudly brought to you by @revolunet, @deltaepsilon, @justinsa and contributors
Features
- highly configurable
- automatic page tracking
- event tracking
- e-commerce (ecommerce.js) support
- enhanced e-commerce (ec.js) support
- multiple-domains
- ga.js (classic) and analytics.js (universal) support
- cross-domain support
- multiple tracking objects
- hybrid mobile application support
- offline mode
- analytics.js advanced debugging support
Installation and Quick Start
The quick start is designed to give you a simple, working example for the most common usage scenario. There are numerous other ways to configure and use this library as explained in the documentation.
1- Installation:
You can install the module from a package manger of your choice directly from the command line
bower install angular-google-analytics
npm i angular-google-analytics
nuget install angular-google-analytics
Or alternatively, grab the dist/angular-google-analytics.min.js and include it in your project
In your application, declare the angular-google-analytics module dependency.
<script src="bower_components/angular-google-analytics/dist/angular-google-analytics.js"></script>
2- In your application, declare dependency injection:
var myApp = angular.module('myModule', ['angular-google-analytics']);
3- Set your Google Analytics account and start tracking:
myApp.config(['AnalyticsProvider', function (AnalyticsProvider) {
AnalyticsProvider.setAccount('UU-XXXXXXX-X');
}]).run(['Analytics', function(Analytics) { }]);
Congratulations! angular-google-analytics is ready and Google Analytics will track your page views once the application is run
Configure Service
app.config(function (AnalyticsProvider) {
});
Configuration Method Chaining
AnalyticsProvider
.logAllCalls(true)
.startOffline(true)
.useECommerce(true, true);
Use Classic Analytics
AnalyticsProvider.useAnalytics(false);
Set Google Analytics Accounts (Required)
AnalyticsProvider.setAccount('UA-XXXXX-xx');
Note: the single account syntax is internally represented as an unnamed account object that will have all properties defined to defaults, except for name.
AnalyticsProvider.setAccount([
{ tracker: 'UA-12345-12', name: "tracker1" },
{ tracker: 'UA-12345-34', name: "tracker2" }
]);
Note: the above account objects will have all properties defined to defaults that are not defined.
AnalyticsProvider.setAccount({
tracker: 'UA-12345-12',
name: "tracker1",
fields: {
cookieDomain: 'foo.example.com',
cookieName: 'myNewName',
cookieExpires: 20000
},
crossDomainLinker: true,
crossLinkDomains: ['domain-1.com', 'domain-2.com'],
displayFeatures: true,
enhancedLinkAttribution: true,
select: function (args) {
return true;
},
set: {
forceSSL: true
},
trackEvent: true,
trackEcommerce: true
});
Note: the above properties are referenced and discussed in proceeding sections.
Note: the cookieConfig
property is being deprecated for the fields
property. At present cookieConfig
is an alias for fields
in an account object.
Use Display Features
AnalyticsProvider.useDisplayFeatures(true);
If set to a truthy value then the display features module is loaded with Google Analytics.
In the case of universal analytics, this value will be used as the default for any tracker that does not have the displayFeatures
property defined. All trackers with displayFeatures: true
will be registered for display features.
Use Enhanced Link Attribution
AnalyticsProvider.useEnhancedLinkAttribution(true);
If set to a truthy value then the enhanced link attribution module is loaded with Google Analytics.
In the case of universal analytics, this value will be used as the default for any tracker that does not have the enhancedLinkAttribution
property defined. All trackers with enhancedLinkAttribution: true
will be registered for enhanced link attribution.
Use Cross Domain Linking
AnalyticsProvider.useCrossDomainLinker(true);
AnalyticsProvider.setCrossLinkDomains(['domain-1.com', 'domain-2.com']);
If set to a truthy value then the cross-linked domains are registered with Google Analytics.
In the case of universal analytics, these values will be used as the default for any tracker that does not have the crossDomainLinker
and crossLinkDomains
properties defined. All trackers with crossDomainLinker: true
will register the cross-linked domains.
Set Cookie Configuration
NOTE: This method is being deprecated. Use the fields
property on the account object instead.
This property is defined for universal analytics account objects only and is set to auto
by default.
AnalyticsProvider.setCookieConfig({
cookieDomain: 'foo.example.com',
cookieName: 'myNewName',
cookieExpires: 20000
});
This cookie configuration will be used as the default for any tracker that does not have the cookieConfig
property defined.
Track Events
This property is defined for universal analytics account objects only and is false by default.
If trackEvent: true
for an account object then all trackEvent
calls will be supported for that account object.
Set trackEvent: false
for an account object that is not tracking events.
Track E-Commerce
This property is defined for universal analytics account objects only. This property defaults to true if e-commerce is enabled (either classic or enhanced) and false otherwise.
If trackEcommerce: true
for an account object then all e-commerce calls will be supported for that account object.
Set trackEcommerce: false
for an account object that is not tracking e-commerce.
Enable E-Commerce
AnalyticsProvider.useECommerce(true, false);
AnalyticsProvider.useECommerce(true, true);
AnalyticsProvider.setCurrency('CDN');
Note: When enhanced e-commerce is enabled, the legacy e-commerce module is disabled and unsupported. This is a requirement of Google Analytics.
Set Route Tracking Behaviors
Note: In order to set route tracking behavior in the $routeProvider you need the ngRoute module in your application. Please refer
to the official angular ngRoute documentation on how to install and use this service.
AnalyticsProvider.trackPages(true);
AnalyticsProvider.trackUrlParams(true);
AnalyticsProvider.ignoreFirstPageLoad(true);
AnalyticsProvider.trackPrefix('my-application');
AnalyticsProvider.setPageEvent('$stateChangeSuccess');
AnalyticsProvider.setRemoveRegExp(/\/\d+?$/);
AnalyticsProvider.readFromRoute(true);
$routeProvider
.when('/sessions', {
templateUrl: 'list.html',
controller: 'ListController'
})
.when('/session/:id',{
templateUrl : 'master.html',
controller: 'MasterController',
pageTrack: '/session'
})
.when('/member/:sessionId/:memberId', {
templateUrl : 'member.html',
controller: 'CardController',
pageTrack: '/member',
})
.otherwise({
templateUrl: '404.html',
doNotTrack: true
});
Set Domain Name
AnalyticsProvider.setDomainName('XXX');
Note: Use the string 'none'
for testing on localhost.
Enable Experiment (universal analytics only)
AnalyticsProvider.setExperimentId('12345');
Note: only a single experiment can be defined.
Support Hybrid Mobile Applications (universal analytics only)
AnalyticsProvider.setHybridMobileSupport(true);
If set to a truthy value then each account object will disable protocol checking and all injected scripts will use the HTTPS protocol.
Delay Script Tag Insertion and Tracker Setup
AnalyticsProvider.delayScriptTag(true);
Offline Mode
AnalyticsProvider.startOffline(true);
Disable Analytics / User Opt-out
AnalyticsProvider.disableAnalytics(true);
Note: Using this configuration option requires that you already know the user wants to opt-out before the analytics script is injected on the page. This is somewhat unlikely for most use cases given the nature of a single page application. This module provides a better alternative with Offline
mode since you can effectively opt the user out of tracking by enabling offline mode at any time during execution.
Service Logging
AnalyticsProvider.logAllCalls(true);
Test Mode
AnalyticsProvider.enterTestMode();
Debug Mode
AnalyticsProvider.enterDebugMode(Boolean);
Using the Analytics Service
IMPORTANT! Due to how Google Analytics works, it is important to remember that you must always call Analytics.pageView();
when you want to push setting changes and function calls to Google Analytics.
Automatic Page View Tracking
If you are relying on automatic page tracking, you need to inject Analytics at least once in your application.
app.run(function(Analytics) {});
Declaring a Controller
app.controller('SampleController', function (Analytics) {
});
Accessing Configuration Settings
The following configuration settings are intended to be immutable. While the values can be changed in this list by the user, this will not impact the behavior of the service as these values are not referenced internally; exceptions are noted below but are not intended to be utilized in such a way by the user. No guarantee will be made for future versions of this service supporting any functionality beyond reading values from this list.
Analytics.configuration.accounts;
Analytics.configuration.universalAnalytics;
Analytics.configuration.crossDomainLinker;
Analytics.configuration.crossLinkDomains;
Analytics.configuration.currency;
Analytics.configuration.debugMode;
Analytics.configuration.delayScriptTag;
Analytics.configuration.disableAnalytics;
Analytics.configuration.displayFeatures;
Analytics.configuration.domainName;
Analytics.configuration.ecommerce;
Analytics.configuration.enhancedEcommerce;
Analytics.configuration.enhancedLinkAttribution;
Analytics.configuration.experimentId;
Analytics.configuration.ignoreFirstPageLoad;
Analytics.configuration.logAllCalls;
Analytics.configuration.pageEvent;
Analytics.configuration.removeRegExp;
Analytics.configuration.traceDebuggingMode;
Analytics.configuration.trackPrefix;
Analytics.configuration.trackRoutes;
Analytics.configuration.trackUrlParams;
Get URL
Analytics.getUrl();
Manual Script Tag Injection and Tracker Setup
If delayScriptTag(true)
was set during configuration then manual script tag injection and tracker setup is required. Otherwise, the script tag and trackers will be automatically injected and configured when the service is instantiated.
Analytics.registerScriptTags();
Analytics.registerTrackers();
Advanced Settings / Custom Dimensions
The set
call allows for advanced configuration and definitions in univeral analytics only. This is a no-op when using classic analytics.
Analytics.set('&uid', 1234);
Analytics.set('dimension1', 'Paid');
Analytics.set('dimension2', 'Paid', 'accountName');
Page Tracking
Analytics.trackPage('/video/detail/XXX');
Analytics.trackPage('/video/detail/XXX', 'Video XXX');
Analytics.trackPage('/video/detail/XXX', 'Video XXX', { dimension15: 'My Custom Dimension', metric18: 8000 });
Event Tracking
Analytics.trackEvent('video', 'play', 'django.mp4');
Analytics.trackEvent('video', 'play', 'django.mp4', 4);
Analytics.trackEvent('video', 'play', 'django.mp4', 4, true);
Analytics.trackEvent('video', 'play', 'django.mp4', 4, true, { dimension15: 'My Custom Dimension', metric18: 8000 });
Track User Timings
The trackTimings
call is available for univeral analytics only. This is a no-op when using classic analytics.
Analytics.trackTimings(timingCategory, timingVar, timingValue, timingLabel);
var endTime = new Date().getTime(),
timeSpent = endTime - startTime;
Analytics.trackTimings('Time to Checkout', 'User Timings', timeSpent);
Classic E-Commerce (ecommerce.js)
Classic e-commerce and enhanced e-commerce are mutually exclusive.
Analytics.addTrans('1', '', '2.42', '0.42', '0', 'Amsterdam', '', 'Netherlands', 'EUR');
Analytics.addItem('1', 'sku-1', 'Test product 1', 'Testing', '1', '1');
Analytics.addItem('1', 'sku-2', 'Test product 2', 'Testing', '1', '1');
Analytics.trackTrans();
Analytics.clearTrans();
Enhanced E-Commerce (ec.js)
Enhanced e-commerce is only available for universal analytics. Enhanced e-commerce and classic e-commerce are mutually exclusive.
Product Impression Tracking
Analytics.addImpression(productId, name, list, brand, category, variant, position, price);
Analytics.pageView();
Analytics.addImpression('sku-1', 'Test Product 1', 'Category List', 'Brand 1', 'Category-1', 'variant-1', '1', '24990');
Analytics.addImpression('sku-2', 'Test Product 2', 'Category List', 'Brand 2', 'Category-1', 'variant-3', '2', '2499');
Analytics.pageView();
Product Click Tracking
Analytics.addProduct(productId, name, category, brand, variant, price, quantity, coupon, position, custom);
Analytics.productClick(listName);
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1');
Analytics.productClick('Search Result');
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1', { dimension4: 'strong', metric2: 5 });
Analytics.productClick('Search Result');
Product Detail Tracking
Analytics.addProduct(productId, name, category, brand, variant, price, quantity, coupon, position);
Analytics.trackDetail();
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1');
Analytics.trackDetail();
Add to Cart Tracking
Analytics.addProduct(productId, name, category, brand, variant, price, quantity, coupon, position);
Analytics.trackCart('add', listName);
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1');
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1');
Analytics.trackCart('add', 'Search Result');
Remove from Cart Tracking
Analytics.addProduct(productId, name, category, brand, variant, price, quantity, coupon, position);
Analytics.trackCart('remove', listName);
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1');
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1');
Analytics.trackCart('remove', 'Search Result');
Checkout Tracking
Analytics.addProduct(productId, name, category, brand, variant, price, quantity, coupon, position);
Analytics.trackCheckout(checkoutStep, optionValue);
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1');
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2499', '1', 'FLAT10', '1');
Analytics.trackCheckout(1, 'Visa');
Transaction Tracking
Analytics.addProduct(productId, name, category, brand, variant, price, quantity, coupon, position);
Analytics.trackTransaction(transactionId, affiliation, revenue, tax, shipping, coupon, list, step, option);
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '2222', '1', 'MEN10', '1');
Analytics.addProduct('sku-2', 'Test Product 2', 'Category-1', 'Brand 2', 'variant-3', '1111', '1', 'WOMEN10', '1');
Analytics.trackTransaction('T1234', 'Online Store - Web', '3333', '10', '200', 'FLAT10', '', '', '');
Promotion Impressions
Analytics.addPromo(productId, name, creative, position);
Analytics.pageView();
Analytics.addPromo('PROMO_1234', 'Summer Sale', 'summer_banner2', 'banner_slot1');
Analytics.pageView();
Note: Before tracking promotion clicks, call pageView, otherwise promotion impressions will be treated as promotion clicks.
Promotion Clicks
Analytics.addPromo(promotionId, promotionName, creative, position);
Analytics.promoClick(promotionName);
Analytics.addPromo('PROMO_1234', 'Summer Sale', 'summer_banner2', 'banner_slot1');
Analytics.promoClick('Summer Sale');
Exception Tracking
Analytics.trackException(description, isFatal);
Analytics.trackException('Function "foo" is undefined on object "bar"', true);
Online / Offline Mode
Analytics.offline(true);
Analytics.offline(false);
In-Memory Queues
Analytics.log;
Analytics.offlineQueue;
Directive
Alternatively, you can use a directive to avoid filling controllers with Analytics.trackEvent();
statements.
Note: the directive does not create an isolate scope.
<button type="button" ga-track-event="['video', 'play', 'django.mp4']"></button>
<button type="button" ga-track-event="['video', 'play', 'django.mp4', 4, true, {dimension15: 'My Custom Dimension', metric18: 8000}]"></button>
You can define the properties on your controller too, $scope.event = ['video', 'play', 'django.mp4']
and reference them.
<button type="button" ga-track-event="event"></button>
ga-track-event-if
is a conditional check. If the attribute value evaluates falsey, the event will NOT be fired. This is useful for user tracking opt-out, etc.
<button type="button" ga-track-event="['video', 'play', 'django.mp4']" ga-track-event-if="shouldTrack"></button>
Troubleshooting
AdBlock EasyPrivacy
AdBlock has a module named EasyPrivacy that is meant to block web tracking scripts. angular-google-analytics.js gets filtered out by the EasyPrivacy blacklist.
Users who are already concatenating and minifying their scripts should not notice a problem as long as the new script name is not also on the EasyPrivacy blacklist. Alternatively, consider changing the file name manually.
Debugging Resources
Chrome Extension: Google Analytics Debugger
Firefox Add-on: Google Analytics Debugger
License
As AngularJS itself, this module is released under the permissive MIT License. Your contributions are always welcome.
Development
After forking you will need to run the following from a command line to get your environment setup:
npm install
bower install
After install you have the following commands available to you from a command line:
grunt lint
npm test
or grunt
or grunt test
npm test-server
or grunt test-server
grunt build
or grunt release
grunt stage