スクリプトをインデックスファイルに手動で追加せずに、AngularアプリにGoogleAnalyticsを追加しようとしています。私の目標は、分析を初期化し、ページビューを追跡するために呼び出すことができる関数を備えたサービスを使用することです。サービスの主要部分は次のとおりです。
export class GoogleAnalyticsService {
private googleAnalyticsId: string;
private renderer2: Renderer2;
private scriptsLoaded: boolean = false;
constructor(
private rendererFactory2: RendererFactory2,
@Inject(DOCUMENT) private _document: Document,
private _config: RuntimeConfigLoaderService,
private _router: Router,
) {
this.renderer2 = this.rendererFactory2.createRenderer(null, null);
this.googleAnalyticsId = this._config.getConfigObjectKey('googleAnalyticsId');
}
init() {
this.insertMainScript();
}
private insertMainScript() {
if (this.googleAnalyticsId) {
const script: HTMLScriptElement = this.renderer2.createElement('script');
script.type = 'text/javascript';
script.onload = this.insertSecondHalfOfScript.bind(this);
script.src = `https://www.googletagmanager.com/gtag/js?id=${this.googleAnalyticsId}`;
script.text = '';
this.renderer2.appendChild(this._document.body, script);
}
}
private insertSecondHalfOfScript() {
const script: HTMLScriptElement = this.renderer2.createElement('script');
script.type = 'text/javascript';
script.src = '';
script.text = `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
`;
this.renderer2.appendChild(this._document.body, script);
this.scriptsLoaded = true;
}
trackSinglePageView(event: NavigationEnd) {
if (this.googleAnalyticsId && this.scriptsLoaded) {
console.log('logging pageview');
gtag('config', this.googleAnalyticsId, { page_path: event.urlAfterRedirects });
}
}
trackPageViews() {
return this._router.events.pipe(
filter((evt: RouterEvent) => evt instanceof NavigationEnd),
tap((event: NavigationEnd) => {
this.trackSinglePageView(event);
}),
);
}
}
から呼び出す主な関数AppComponent
はinit
です。これにより、スクリプトがページに挿入されます。アプリケーションのロードを見ると、これらのスクリプトが追加されているのがわかります。またhttps://www.googletagmanager.com/gtag/js
、開発者ツールの[ネットワーク]タブにスクリプトの読み込みが表示されます。したがって、スクリプトは間違いなくそこにあります。
次に、でinit
関数を呼び出した後、関数AppComponent
を呼び出しtrackPageViews
て、返されたObservableをサブスクライブします。上記のスクリプトが読み込まれるまですべてのルーターイベントを除外してから、イベントではないすべてのイベントを除外しNavigationEnd
ます。スクリプトがロードされ、それがNavigationEndイベントである場合、trackSinglePageView
関数gtag
は必要なデータとともに呼び出されます。ただし、これが発生すると、次のエラーが発生します。
core.js:6189 ERROR ReferenceError: gtag is not defined
at GoogleAnalyticsService.trackSinglePageView (google-analytics.service.ts:58)
at TapSubscriber._tapNext (google-analytics.service.ts:69)
at TapSubscriber._next (tap.js:40)
at TapSubscriber.next (Subscriber.js:49)
at FilterSubscriber._next (filter.js:33)
at FilterSubscriber.next (Subscriber.js:49)
at Subject.next (Subject.js:39)
at SafeSubscriber._next (router.js:7593)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
at SafeSubscriber.next (Subscriber.js:122)
サービスを使用して分析スクリプトをロードしhead
てアプリのindex.htmlファイルに配置し、ページビューを追跡しない場合、コンソールでエラーは発生しません。したがって、スクリプトはロードさgtag
れていhead
ますが、分析スクリプトがに含まれていない限り、まだ定義されていないようです。
これを回避する方法はありますか?私はここで何か間違ったことをしていますか?どんなアイデアでも大歓迎です。
したがって、insertSecondHalfOfScript
関数で作成されたスクリプトのテキストは実行されなかったことがわかります。gtag
そのページで利用できるようになっているようです。そのため、そのテキスト属性にコードを追加する代わりに、コードをアセットファイルに入れて、insertMainScript
関数にスクリプトをロードするようにロードしました。したがって、開始フローは次のようになります。
init() {
this.insertMainScript();
}
private insertMainScript() {
if (this.googleAnalyticsId) {
const script: HTMLScriptElement = this.renderer2.createElement('script');
script.type = 'text/javascript';
script.onload = this.insertSecondHalfOfScript.bind(this);
script.src = `https://www.googletagmanager.com/gtag/js?id=${this.googleAnalyticsId}`;
script.text = '';
this.renderer2.appendChild(this._document.body, script);
}
}
private insertSecondHalfOfScript() {
const script: HTMLScriptElement = this.renderer2.createElement('script');
script.type = 'text/javascript';
script.src = '/assets/scripts/analytics/analytics-starting-script.js';
script.text = '';
this.renderer2.appendChild(this._document.body, script);
script.onload = () => {
this.scriptsLoaded = true;
};
}
このように2番目のスクリプトをロードすると、ReferenceError
以前に取得していたものが取得できなくなったため、機能しているようです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加