angular 4でGoogle Analyticsを使用しようとしていますが、tsでga.jsに@typeが見つかりません。
迅速な解決策として、すべてのコンポーネントでこれを使用しました。
declare let ga: any;
私がそれを解決した方法に従って:
GAスクリプトを現在のtrackingIdとユーザーとともに挿入するGAを動的にロードする関数を作成します。
loadGA(userId) {
if (!environment.GAtrackingId) return;
let scriptId = 'google-analytics';
if (document.getElementById(scriptId)) {
return;
}
var s = document.createElement('script') as any;
s.type = "text/javascript";
s.id = scriptId;
s.innerText = "(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','//www.google-analytics.com/analytics.js','ga');ga('create', { trackingId: '" + **environment.GAtrackingId** + "', cookieDomain: 'auto', userId: '" + **userId** + "'});ga('send', 'pageview', '/');";
document.getElementsByTagName("head")[0].appendChild(s);
}
必要なメソッドを実装するサービスを作成します。
import { Injectable } from '@angular/core';
import { environment } from '../../../environments/environment';
declare let ga: any;
@Injectable()
export class GAService {
constructor() {
}
/**
* Checks if the GA script was loaded.
*/
private useGA() : boolean {
return environment.GAtrackingId && typeof ga !== undefined;
}
/**
* Sends the page view to GA.
* @param {string} page The path portion of a URL. This value should start with a slash (/) character.
*/
sendPageView(
page: string
) {
if (!this.useGA()) return;
if (!page.startsWith('/')) page = `/${page}`;
ga('send', 'pageview', page);
}
/**
* Sends the event to GA.
* @param {string} eventCategory Typically the object that was interacted with (e.g. 'Video')
* @param {string} eventAction The type of interaction (e.g. 'play')
*/
sendEvent(
eventCategory: string,
eventAction: string
) {
if (!this.useGA()) return;
ga('send', 'event', eventCategory, eventAction);
}
}
次に、コンポーネントに注入されたサービスを最終的に使用します。
constructor(private ga: GAService) {}
ngOnInit() { this.ga.sendPageView('/join'); }
まず、devDependencies
にGoogleアナリティクスのタイピングをインストールする必要があります
npm install --save-dev @types/google.analytics
次に、ベースindex.html
にトラッキングコードを追加し、次のように最後の行を削除します。
<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>
次のステップは、イベント追跡のためにホームコンポーネントコンストラクターを更新することです。
constructor(public router: Router) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
ga('set', 'page', event.urlAfterRedirects);
ga('send', 'pageview');
}
});
}
特定のイベントを追跡する場合は、サービスを作成し、イベント追跡を実装するコンポーネントにサービスを注入することもできます。
// ./src/app/services/google-analytics-events-service.ts
import {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 });
}
}
たとえば、ホームコンポーネントのクリックを追跡する場合、必要なことはGoogleAnalyticsEventsService
を挿入し、emitEvent()
メソッドを呼び出すことだけです。
更新されたホームコンポーネントのソースコード:
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);
}
ここで誰も言及していないことに驚いていますGoogleのタグマネージャー 、新しいIDを追加するたびに)。
ここに私が今日思い付いた解決策があります。これは、他の回答で既に言及された解決策のバリエーションであり、Googleのタグマネージャースクリプトへのアダプターです。 ga()
からgtag()
に移行した人(私の知る限り 推奨 の移行)に役立つと思います。
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);
}
});
}
}
前提条件:
app.module.ts
のimports []セクションでサービスを宣言します。<router-outlet>
タグを保持する上位レベルのコンポーネント)で、AnalyticsServiceを挿入し、できるだけ早くthis.analytics.init()
を呼び出します(例:ngOnInit)googleAnalyticsKey: 'UA-XXXXXXX-XXXX'
として追加します(Angular 5で動作します)
(@Laisoアンサーを使用)
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
});
}
}
}
// ... 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 event
this.googleAnalyticsService.emitEvent("testCategory", "testAction", "testLabel", 10);
ルーターイベントをサブスクライブするservice
を作成し、app.module.ts
に挿入できるため、すべてのコンポーネントに挿入する必要はありません。
@Injectable()
export class GoogleAnalyticsService {
constructor(router: Router) {
if (!environment.production) return; // <-- If you want to enable GA only in production
router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
ga('set', 'page', event.url);
ga('send', 'pageview');
}
})
}
Gaがウィンドウレベルでグローバルに定義されている場合、型チェックを回避するには、次のようにします。
window["ga"]('send', {
hitType: 'event',
eventCategory: 'eventCategory',
eventAction: 'eventAction'
});
それが役に立てば幸い。
個人的に、私は簡単にそれを簡単に見つけました:
<app-root>
の後にGAトラッキングコードを追加する(上記を参照)私のapp.component.ts
にこれを追加しました:
import {Component, OnInit} from '@angular/core';
import {NavigationEnd, Router} from '@angular/router';
import {Angulartics2GoogleAnalytics} from 'angulartics2/ga';
import {filter} from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
constructor(private ga: Angulartics2GoogleAnalytics,
private router: Router) {
}
ngOnInit() {
this.router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe((event: NavigationEnd) =>
this.ga.pageTrack(event.urlAfterRedirects));
}
}
上記と大差はありませんが、テストがはるかに簡単になります。
Segmentスクリプトをindex.html
に埋め込み、分析ライブラリをwindow
オブジェクトに拡張することをお勧めします。
declare global {
interface Window { analytics: any; }
}
次に、(click)
イベントハンドラーに追跡呼び出しを追加します。
@Component({
selector: 'app-signup-btn',
template: `
<button (click)="trackEvent()">
Signup with Segment today!
</button>
`
})
export class SignupButtonComponent {
trackEvent() {
window.analytics.track('User Signup');
}
}
私は https://github.com/segmentio/analytics-angular のメンテナーです。単一のAPIを使用して顧客データを管理し、追加のコードを作成せずに他の分析ツール(250以上の宛先をサポート)に統合して、この問題を解決する場合は、チェックアウトすることをお勧めします。 ????