Angular 4+ using Google Analytics
First of all, you need to install typings for Google Analytics in your devDependencies
npm install --save-dev @types/google.analytics
Then add your tracking code in the base index.html
, and remove the last line as shown bellow:
<body> <app-root>Loading...</app-root> <script> (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','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-XXXXXX-ID', 'auto'); // <- add the UA-ID // <- remove the last line </script></body>
The next step consists to update your home component constructor for event tracking.
constructor(public router: Router) { this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { ga('set', 'page', event.urlAfterRedirects); ga('send', 'pageview'); } }); }
If you want to track some specific event, you can also create a service and inject it into any component that you want to implement event tracking.
// ./src/app/services/google-analytics-events-service.tsimport {Injectable} from "@angular/core";@Injectable()export class GoogleAnalyticsEventsService { public emitEvent(eventCategory: string, eventAction: string, eventLabel: string = null, eventValue: number = null) { ga('send', 'event', { eventCategory, eventLabel, eventAction, eventValue }); }}
So if you want track a click on your home component for example, all you need to do is to inject the GoogleAnalyticsEventsService
and call the emitEvent()
method.
The updated home component source code:
constructor(public router: Router, public googleAnalyticsEventsService: GoogleAnalyticsEventsService) { this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { ga('set', 'page', event.urlAfterRedirects); ga('send', 'pageview'); } }); } submitEvent() { // event fired from home.component.html element (button, link, ... ) this.googleAnalyticsEventsService.emitEvent("testCategory", "testAction", "testLabel", 10); }
I'm surprised nobody here mentioned Google's Tag Manager yet (which is the version of the script that the Google Analytics console outputs for me in the last few years, whenever I add a new identity).
Here's a solution that I came up with today, which is a variation of the solutions already mentioned in the other answers, adapter to Google's Tag Manager script. I think it would be useful for people who migrated from ga()
to gtag()
(a migration that is recommended as far as I know).
analytics.service.ts
declare var gtag: Function;@Injectable({ providedIn: 'root'})export class AnalyticsService { constructor(private router: Router) { } public event(eventName: string, params: {}) { gtag('event', eventName, params); } public init() { this.listenForRouteChanges(); try { const script1 = document.createElement('script'); script1.async = true; script1.src = 'https://www.googletagmanager.com/gtag/js?id=' + environment.googleAnalyticsKey; document.head.appendChild(script1); const script2 = document.createElement('script'); script2.innerHTML = ` window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '` + environment.googleAnalyticsKey + `', {'send_page_view': false}); `; document.head.appendChild(script2); } catch (ex) { console.error('Error appending google analytics'); console.error(ex); } } private listenForRouteChanges() { this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { gtag('config', environment.googleAnalyticsKey, { 'page_path': event.urlAfterRedirects, }); console.log('Sending Google Analytics hit for route', event.urlAfterRedirects); console.log('Property ID', environment.googleAnalyticsKey); } }); }}
Prerequisites:
- Declare the service in the imports[] section of your
app.module.ts
. - In your app.component.ts (or whichever higher level component holds the
<router-outlet>
tag in its template), inject the AnalyticsService and callthis.analytics.init()
as early as possible (e.g. ngOnInit) - In the environment.ts (in my case - environment.prod.ts), add the Analytics ID as
googleAnalyticsKey: 'UA-XXXXXXX-XXXX'
Load google analytics, using environment vars, the async way;
(Works on Angular 5)
(Using @Laiso answer)
google-analytics.service.ts
import {Injectable} from '@angular/core';import {NavigationEnd, Router} from '@angular/router';declare var ga: Function;@Injectable()export class GoogleAnalyticsService { constructor(public router: Router) { this.router.events.subscribe(event => { try { if (typeof ga === 'function') { if (event instanceof NavigationEnd) { ga('set', 'page', event.urlAfterRedirects); ga('send', 'pageview'); console.log('%%% Google Analytics page view event %%%'); } } } catch (e) { console.log(e); } }); } /** * Emit google analytics event * Fire event example: * this.emitEvent("testCategory", "testAction", "testLabel", 10); * @param {string} eventCategory * @param {string} eventAction * @param {string} eventLabel * @param {number} eventValue */ public emitEvent(eventCategory: string, eventAction: string, eventLabel: string = null, eventValue: number = null) { if (typeof ga === 'function') { ga('send', 'event', { eventCategory: eventCategory, eventLabel: eventLabel, eventAction: eventAction, eventValue: eventValue }); } }}
Inside app.component or whatever component:
// ... import stuff import { environment } from '../../../environments/environment'; // ... declarations constructor(private googleAnalyticsService: GoogleAnalyticsService){ this.appendGaTrackingCode(); } private appendGaTrackingCode() { try { const script = document.createElement('script'); script.innerHTML = ` (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','https://www.google-analytics.com/analytics.js','ga'); ga('create', '` + environment.googleAnalyticsKey + `', 'auto'); `; document.head.appendChild(script); } catch (ex) { console.error('Error appending google analytics'); console.error(ex); } }// Somewhere else we can emit a new ga eventthis.googleAnalyticsService.emitEvent("testCategory", "testAction", "testLabel", 10);