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