Skip to content

Commit 1fbc4c4

Browse files
authored
Update to allow for multiple instance of gtag with different datalayer names (#6655)
* Update to look for datalayer of gtag script * Update tests and remove console.logs * Update doc string to reflect function changes * Update function name to more accurately reflect usage * Adding changeset
1 parent 63f4eca commit 1fbc4c4

File tree

7 files changed

+45
-17
lines changed

7 files changed

+45
-17
lines changed

.changeset/slow-forks-tease.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@firebase/analytics': patch
3+
---
4+
5+
Update to allow for multiple instance of gtag with different datalayer names

packages/analytics/src/helpers.test.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
import { GtagCommand } from './constants';
3030
import { Deferred } from '@firebase/util';
3131
import { ConsentSettings } from './public-types';
32+
import { removeGtagScripts } from '../testing/gtag-script-util';
3233

3334
const fakeMeasurementId = 'abcd-efgh-ijkl';
3435
const fakeAppId = 'my-test-app-1234';
@@ -46,6 +47,10 @@ const fakeDynamicConfig: DynamicConfig = {
4647
const fakeDynamicConfigPromises = [Promise.resolve(fakeDynamicConfig)];
4748

4849
describe('Gtag wrapping functions', () => {
50+
afterEach(() => {
51+
removeGtagScripts();
52+
});
53+
4954
it('getOrCreateDataLayer is able to create a new data layer if none exists', () => {
5055
delete window['dataLayer'];
5156
expect(getOrCreateDataLayer('dataLayer')).to.deep.equal([]);
@@ -57,14 +62,24 @@ describe('Gtag wrapping functions', () => {
5762
});
5863

5964
it('insertScriptIfNeeded inserts script tag', () => {
60-
expect(findGtagScriptOnPage()).to.be.null;
61-
insertScriptTag('customDataLayerName', fakeMeasurementId);
62-
const scriptTag = findGtagScriptOnPage();
65+
const customDataLayerName = 'customDataLayerName';
66+
expect(findGtagScriptOnPage(customDataLayerName)).to.be.null;
67+
insertScriptTag(customDataLayerName, fakeMeasurementId);
68+
const scriptTag = findGtagScriptOnPage(customDataLayerName);
6369
expect(scriptTag).to.not.be.null;
6470
expect(scriptTag!.src).to.contain(`l=customDataLayerName`);
6571
expect(scriptTag!.src).to.contain(`id=${fakeMeasurementId}`);
6672
});
6773

74+
// The test above essentially already touches this functionality but it is still valuable
75+
it('findGtagScriptOnPage returns gtag instance with matching data layer name', () => {
76+
const defaultDataLayerName = 'dataLayer';
77+
insertScriptTag(defaultDataLayerName, fakeMeasurementId);
78+
const scriptTag = findGtagScriptOnPage(defaultDataLayerName);
79+
expect(scriptTag!.src).to.contain(`l=${defaultDataLayerName}`);
80+
expect(findGtagScriptOnPage('NON_EXISTENT_DATA_LAYER_ID')).to.be.null;
81+
});
82+
6883
describe('wrapOrCreateGtag() when user has not previously inserted a gtag script tag on this page', () => {
6984
afterEach(() => {
7085
delete window['gtag'];

packages/analytics/src/helpers.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,19 @@ export function wrapOrCreateGtag(
318318
}
319319

320320
/**
321-
* Returns first script tag in DOM matching our gtag url pattern.
321+
* Returns the script tag in the DOM matching both the gtag url pattern
322+
* and the provided data layer name.
322323
*/
323-
export function findGtagScriptOnPage(): HTMLScriptElement | null {
324+
export function findGtagScriptOnPage(
325+
dataLayerName: string
326+
): HTMLScriptElement | null {
324327
const scriptTags = window.document.getElementsByTagName('script');
325328
for (const tag of Object.values(scriptTags)) {
326-
if (tag.src && tag.src.includes(GTAG_URL)) {
329+
if (
330+
tag.src &&
331+
tag.src.includes(GTAG_URL) &&
332+
tag.src.includes(dataLayerName)
333+
) {
327334
return tag;
328335
}
329336
}

packages/analytics/src/index.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
import { FirebaseApp } from '@firebase/app';
2727
import { GtagCommand } from './constants';
2828
import { findGtagScriptOnPage } from './helpers';
29-
import { removeGtagScript } from '../testing/gtag-script-util';
29+
import { removeGtagScripts } from '../testing/gtag-script-util';
3030
import { Deferred } from '@firebase/util';
3131
import { AnalyticsError } from './errors';
3232
import { logEvent } from './api';
@@ -150,7 +150,7 @@ describe('FirebaseAnalytics instance tests', () => {
150150
after(() => {
151151
delete window['gtag'];
152152
delete window['dataLayer'];
153-
removeGtagScript();
153+
removeGtagScripts();
154154
fetchStub.restore();
155155
clock.restore();
156156
idbOpenStub.restore();
@@ -208,7 +208,7 @@ describe('FirebaseAnalytics instance tests', () => {
208208
afterEach(() => {
209209
delete window['gtag'];
210210
delete window['dataLayer'];
211-
removeGtagScript();
211+
removeGtagScripts();
212212
fetchStub.restore();
213213
clock.restore();
214214
warnStub.restore();
@@ -304,7 +304,7 @@ describe('FirebaseAnalytics instance tests', () => {
304304
after(() => {
305305
delete window[customGtagName];
306306
delete window[customDataLayerName];
307-
removeGtagScript();
307+
removeGtagScripts();
308308
fetchStub.restore();
309309
clock.restore();
310310
idbOpenStub.restore();
@@ -349,13 +349,13 @@ describe('FirebaseAnalytics instance tests', () => {
349349
// Successfully resolves fake IDB open request.
350350
fakeRequest.onsuccess();
351351
await initializationPromisesMap[fakeAppParams.appId];
352-
expect(findGtagScriptOnPage()).to.not.be.null;
352+
expect(findGtagScriptOnPage('dataLayer')).to.not.be.null;
353353
expect(typeof window['gtag']).to.equal('function');
354354
expect(Array.isArray(window['dataLayer'])).to.be.true;
355355

356356
delete window['gtag'];
357357
delete window['dataLayer'];
358-
removeGtagScript();
358+
removeGtagScripts();
359359
fetchStub.restore();
360360
idbOpenStub.restore();
361361
});

packages/analytics/src/initialize-analytics.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { DynamicConfig } from './types';
2828
import { FirebaseApp } from '@firebase/app';
2929
import { Deferred } from '@firebase/util';
3030
import { _FirebaseInstallationsInternal } from '@firebase/installations';
31-
import { removeGtagScript } from '../testing/gtag-script-util';
31+
import { removeGtagScripts } from '../testing/gtag-script-util';
3232
import { setDefaultEventParameters } from './api';
3333
import {
3434
defaultConsentSettingsForInit,
@@ -68,7 +68,7 @@ describe('initializeAnalytics()', () => {
6868
});
6969
afterEach(() => {
7070
fetchStub.restore();
71-
removeGtagScript();
71+
removeGtagScripts();
7272
});
7373
it('gets FID and measurement ID and calls gtag config with them', async () => {
7474
stubFetch();

packages/analytics/src/initialize-analytics.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,9 @@ export async function _initializeAnalytics(
119119
fidPromise
120120
]);
121121

122-
// Detect if user has already put the gtag <script> tag on this page.
123-
if (!findGtagScriptOnPage()) {
122+
// Detect if user has already put the gtag <script> tag on this page with the passed in
123+
// data layer name.
124+
if (!findGtagScriptOnPage(dataLayerName)) {
124125
insertScriptTag(dataLayerName, dynamicConfig.measurementId);
125126
}
126127

packages/analytics/testing/gtag-script-util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717
import { GTAG_URL } from '../src/constants';
1818

19-
export function removeGtagScript(): void {
19+
export function removeGtagScripts(): void {
2020
const scriptTags = window.document.getElementsByTagName('script');
2121
for (const tag of Object.values(scriptTags)) {
2222
if (tag.src) {

0 commit comments

Comments
 (0)