【Angular】Googleアナリティクスをページ毎に設定する

Googleアナリティクスをページ毎に設定する

SPA構築ではページ遷移はフロント側で行います。Angularももちろん同じです。

ということで、Googleアナリティクスの設定もページ遷移のたびにトラッキングするようにAngularで設定する必要があります。

そこで今回はAngularでのGoogleアナリティクスの設定方法についてご紹介します。
(記事中では gtag.js での設定方法を解説します。)

Googleアナリティクスの読み込み

まずはじめにGoogleアナリティクスを index.html で読み込みます。
bodyの閉じタグ直前に挿入します。

<!doctype html>
<html lang="ja">
<head>
...
</head>
<body>
  ...

  <!-- Global site tag (gtag.js) - Google Analytics -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=UA-*******-*"></script>
  <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
  </script>
</body>
</html>

※ 挿入コードにあらかじめ記載されている gtag('config', 'UA-********-*'); の行は削除しておきます。削除しておかないと1ページビュー多くカウントされてしまいます。

Googleアナリティクス用のサービスを作成する

次にGoogleアナリティクス用のサービスを作成します。
なぜサービスにするかというと、Googleアナリティクスのイベントトラッキングで各コンポーネントからイベントを送信するケースが多いので、始めからサービスとして切り出します。

また、プロジェクトをまたいでコードの使い回しができるので便利です。

ga.service.ts

import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';

declare let gtag: any; // グローバル変数gtagを解決

@Injectable()
export class GaService {

  constructor() {}

  /**
   * GAの読み込みをチェック
   */
  private useGA(): boolean {
    return typeof gtag !== undefined;
  }

  /**
   * ページトラッキング
   * @param  {string} url URLのパス。スラッシュで始まる必要がある。
   */
  sendPageView(url: string): void {
    if (!this.useGA()) { return; }
    if (!url.startsWith('/')) { url = /${url}; }
    gtag('config', environment.analytics.id, {
      'page_path': url
    });
  }

  /**
   * イベントトラッキング
   * @param  {string} eventCategory (e.g. 'Video')
   * @param  {string} eventAction (e.g. 'play')
   * @param  {string} eventLabel (e.g. 'play campaign CM')
   */
  sendEvent(eventName: string, eventCategory: string, eventAction: string, eventLabel: any): void {
    if (!this.useGA()) { return; }
    gtag('event', eventName, {
      event_category: eventCategory,
      event_action: eventAction,
      event_label: eventLabel
    });
  }
}

sendPageView にはurl文字列を、sendEvent には各設定を渡す実装です。

あわせてenvironments/environment.ts にGoogleアナリティクスのIDを設定しておきましょう。

environments/environment.ts, environment.prod.ts

export const environment = {
  production: false,
  analytics: {
    id: 'UA-*******-*' // IDを設定する、environment.prod.tsにも
  },
  ...
};

ルートコンポーネントでトラッキング設定

仕上げにAppComponentなどのルートコンポーネントで、Router を利用してページトラッキング設定をします。

app.component.ts

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { GaService } from './core/ga.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  constructor(
    private router: Router,
    private gaService: GaService
  ) {}

  ngOnInit() {
    // tracking
    this.router.events
      .filter(event => event instanceof NavigationEnd)
      .subscribe((params: any) => {
        this.gaService.sendPageView(params.url);
      });
  }

}

Routerの NavigationEnd イベントを利用して、Routerから取得できるURLを先ほど作成した GaService.sendPageView に渡します。

router.events.filterがエラーの場合

Property 'filter' does not exist on type Observable<Event>

上記のエラーが発生する場合、RxJSのfilterオペレータの追加が必要です。

RxJS 5.xの場合

import 'rxjs/add/operator/filter';

RxJS 6.xの場合(Angular 6〜)

import { filter } from 'rxjs/operators';

...

this.router.events
  .pipe(
    filter(event => event instanceof NavigationEnd)
  )
  .subscribe((params: any) => {
    this.gaService.sendPageView(params.url);
  });

filterオペレータをインポートして、router.events のpipeメソッドに渡します。

イベントトラッキング

import { Component } from '@angular/core';
import { GaService } from './ga.service';

@Component({
  selector: 'app-some',
  templateUrl: './some.component.html',
  styleUrls: ['./some.component.scss']
})

class SomeComponent {

  constructor(private gaService: GaService) {}

  handleClick(event) {
    this.gaService.sendEvent('User Action', 'click', 'conversion', '3000');
  }

}
Googleアナリティクスをページ毎に設定する

更新情報はTwitterでも配信しています