Angular 4+ using Google Analytics Angular 4+ using Google Analytics typescript typescript

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 call this.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);