diff --git a/src/app/statistics/google-analytics.service.spec.ts b/src/app/statistics/google-analytics.service.spec.ts index 0c6bc2bc51..24c5345260 100644 --- a/src/app/statistics/google-analytics.service.spec.ts +++ b/src/app/statistics/google-analytics.service.spec.ts @@ -1,20 +1,19 @@ import { GoogleAnalyticsService } from './google-analytics.service'; -import { Angulartics2GoogleAnalytics } from 'angulartics2'; +import { Angulartics2GoogleTagManager } from 'angulartics2'; import { ConfigurationDataService } from '../core/data/configuration-data.service'; -import { - createFailedRemoteDataObject$, - createSuccessfulRemoteDataObject$ -} from '../shared/remote-data.utils'; +import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils'; import { ConfigurationProperty } from '../core/shared/configuration-property.model'; describe('GoogleAnalyticsService', () => { const trackingIdProp = 'google.analytics.key'; const trackingIdTestValue = 'mock-tracking-id'; const innerHTMLTestValue = 'mock-script-inner-html'; + const srcTestValue = 'mock-script-src'; let service: GoogleAnalyticsService; - let angularticsSpy: Angulartics2GoogleAnalytics; + let angularticsSpy: Angulartics2GoogleTagManager; let configSpy: ConfigurationDataService; let scriptElementMock: any; + let srcSpy: any; let innerHTMLSpy: any; let bodyElementSpy: HTMLBodyElement; let documentSpy: Document; @@ -28,18 +27,21 @@ describe('GoogleAnalyticsService', () => { }); beforeEach(() => { - angularticsSpy = jasmine.createSpyObj('angulartics2GoogleAnalytics', [ + angularticsSpy = jasmine.createSpyObj('Angulartics2GoogleTagManager', [ 'startTracking', ]); configSpy = createConfigSuccessSpy(trackingIdTestValue); scriptElementMock = { + set src(newVal) { /* noop */ }, + get src() { return innerHTMLTestValue; }, set innerHTML(newVal) { /* noop */ }, - get innerHTML() { return innerHTMLTestValue; } + get innerHTML() { return srcTestValue; } }; innerHTMLSpy = spyOnProperty(scriptElementMock, 'innerHTML', 'set'); + srcSpy = spyOnProperty(scriptElementMock, 'src', 'set'); bodyElementSpy = jasmine.createSpyObj('body', { appendChild: scriptElementMock, @@ -106,19 +108,22 @@ describe('GoogleAnalyticsService', () => { describe('when the tracking id is non-empty', () => { it('should create a script tag whose innerHTML contains the tracking id', () => { service.addTrackingIdToPage(); - expect(documentSpy.createElement).toHaveBeenCalledTimes(1); + expect(documentSpy.createElement).toHaveBeenCalledTimes(2); expect(documentSpy.createElement).toHaveBeenCalledWith('script'); // sanity check expect(documentSpy.createElement('script')).toBe(scriptElementMock); + expect(srcSpy).toHaveBeenCalledTimes(1); + expect(srcSpy.calls.argsFor(0)[0]).toContain(trackingIdTestValue); + expect(innerHTMLSpy).toHaveBeenCalledTimes(1); expect(innerHTMLSpy.calls.argsFor(0)[0]).toContain(trackingIdTestValue); }); it('should add a script to the body', () => { service.addTrackingIdToPage(); - expect(bodyElementSpy.appendChild).toHaveBeenCalledTimes(1); + expect(bodyElementSpy.appendChild).toHaveBeenCalledTimes(2); }); it('should start tracking', () => { diff --git a/src/app/statistics/google-analytics.service.ts b/src/app/statistics/google-analytics.service.ts index 0b52f54c4f..6bdff53d52 100644 --- a/src/app/statistics/google-analytics.service.ts +++ b/src/app/statistics/google-analytics.service.ts @@ -1,5 +1,5 @@ import { Inject, Injectable } from '@angular/core'; -import { Angulartics2GoogleAnalytics } from 'angulartics2'; +import { Angulartics2GoogleTagManager } from 'angulartics2'; import { ConfigurationDataService } from '../core/data/configuration-data.service'; import { getFirstCompletedRemoteData } from '../core/shared/operators'; import { isEmpty } from '../shared/empty.util'; @@ -13,7 +13,8 @@ import { DOCUMENT } from '@angular/common'; export class GoogleAnalyticsService { constructor( - private angulartics: Angulartics2GoogleAnalytics, + // private angulartics: Angulartics2GoogleAnalytics, + private angulartics: Angulartics2GoogleTagManager, private configService: ConfigurationDataService, @Inject(DOCUMENT) private document: any, ) { } @@ -36,15 +37,16 @@ export class GoogleAnalyticsService { // make sure we received a tracking id if (isEmpty(trackingId)) { return; } - // add trackingId snippet to page + // add GTag snippet to page const keyScript = this.document.createElement('script'); - keyScript.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', '${trackingId}', 'auto');`; + keyScript.src = `https://www.googletagmanager.com/gtag/js?id=${trackingId}`; this.document.body.appendChild(keyScript); + const libScript = this.document.createElement('script'); + libScript.innerHTML = `window.dataLayer = window.dataLayer || [];function gtag(){window.dataLayer.push(arguments);} + gtag('js', new Date());gtag('config', '${trackingId}');`; + this.document.body.appendChild(libScript); + // start tracking this.angulartics.startTracking(); }); diff --git a/src/modules/app/server-app.module.ts b/src/modules/app/server-app.module.ts index 35fa050d6f..8565db3e23 100644 --- a/src/modules/app/server-app.module.ts +++ b/src/modules/app/server-app.module.ts @@ -6,8 +6,7 @@ import { ServerModule, ServerTransferStateModule } from '@angular/platform-serve import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { Angulartics2 } from 'angulartics2'; -import { Angulartics2GoogleAnalytics } from 'angulartics2'; +import { Angulartics2, Angulartics2GoogleTagManager } from 'angulartics2'; import { AppComponent } from '../../app/app.component'; @@ -60,7 +59,7 @@ export function createTranslateLoader(transferState: TransferState) { useClass: Angulartics2Mock }, { - provide: Angulartics2GoogleAnalytics, + provide: Angulartics2GoogleTagManager, useClass: AngularticsProviderMock }, {