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'); } }