Add Google Analytics to an Angular app

Published December 01, 2021

Here's how you can add Google Analytics to an Angular app using Google's Tag Manager.

Environment variable

We'll start by adding the Google Analytics Property ID to the Angular application's environment variables.

Open the environment.ts and add the following.

export const environment = {
  production: false,
  googleAnalyticsId: undefined,
};

Now, open the environment.prod.ts and add the following.

export const environment = {
  production: true,
  googleAnalyticsId: '[G-YOUR-KEY-HERE]',
};

Service class

Let's create a GoogleAnalyticsService in a file called googleAnalytics.service.ts. This file can be placed in an analytics folder within the Angular app folder. Add the following code to this new file.

import { Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { environment } from '../../environments/environment';

declare var gtag: Function;

@Injectable({
  providedIn: 'root',
})
export class GoogleAnalyticsService {
  constructor(private router: Router) {}

  public initialize() {
    this.onRouteChange();

    // dynamically add analytics scripts to document head
    try {
      const url = 'https://www.googletagmanager.com/gtag/js?id=';
      const gTagScript = document.createElement('script');      
      gTagScript.async = true;
      gTagScript.src = `${url}${environment.googleAnalyticsId}`;
      document.head.appendChild(gTagScript);

      const dataLayerScript = document.createElement('script');
      dataLayerScript.innerHTML = `
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', '${environment.googleAnalyticsId}', {'send_page_view': false});`;
      document.head.appendChild(dataLayerScript);
    } catch (e) {
      console.error('Error adding Google Analytics', e);
    }
  }

  // track visited routes
  private onRouteChange() {    
    this.router.events.subscribe((event) => {
      if (event instanceof NavigationEnd) {
        gtag('config', environment.googleAnalyticsId, {
          page_path: event.urlAfterRedirects,
        });
      }
    });
  }

  // use gtag.js to send Google Analytics Events
  public event(action: string, eventCategory?: string, eventLabel?: string, value?: string) {
    gtag('event', action, {
      ...(eventCategory && { event_category: eventCategory }),
      ...(eventLabel && { event_label: eventLabel }),
      ...(value && { value: value }),
    });
  }
}

Invoke the service

We'll now modify the AppComponent in the app.component.ts file. We'll assume that AppComponent is the component in the application that contains the <router-outlet> tag in its template. If that's not the case, then you can modify the corresponding component and template instead.

import { Component, OnInit } from '@angular/core';
import { environment } from '../environments/environment';
import { GoogleAnalyticsService } from './analytics/google-analytics.service';

@Component({
  selector: 'app',
  template: '<router-outlet></router-outlet>',
})
export class AppComponent implements OnInit {
  constructor(private readonly googleAnalyticsService: GoogleAnalyticsService) {}

  ngOnInit() {
    if (environment.production) {
      this.googleAnalyticsService.initialize();
    }
  }
}

In this component, we are calling the initialize function as early as possible within ngOnInit. In this example, we make sure to add analytics tracking only to the production environment of the application.

Testing it out

To test that Google Analytics has been added properly, we can add console.log statements in the GoogleAnalyticsService class.

private onRouteChange() {
  this.router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {
      gtag('config', environment.googleAnalyticsKey, {
        'page_path': event.urlAfterRedirects,
      });
      console.log('Sending Google Analytics tracking for: ', event.urlAfterRedirects);
      console.log('Google Analytics property ID: ', environment.googleAnalyticsKey);
    }
  });
}

We should now see the two statements being logged to our console every time that we navigate to a new route within the Angular application.