Skip to content

Commit 6eadc87

Browse files
authored
Merge pull request #848 from ably/web-4381-track-route-changes-as-page-views
[WEB-4381] chore: conditionally allow gtm page view tracking
2 parents 5637559 + a38d1ac commit 6eadc87

File tree

7 files changed

+55
-11
lines changed

7 files changed

+55
-11
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ably/ui",
3-
"version": "17.5.0",
3+
"version": "17.5.2",
44
"description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.",
55
"repository": {
66
"type": "git",

src/core/insights/command-queue.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Command,
44
InsightsConfig,
55
InsightsIdentity,
6+
TrackPageViewOptions,
67
} from "./types";
78
import { InsightsService } from "./service";
89
import * as logger from "./logger";
@@ -117,7 +118,7 @@ export class InsightsCommandQueue implements AnalyticsService {
117118
enableDebugMode(): void {}
118119
disableDebugMode(): void {}
119120
identify(_identity: InsightsIdentity): void {}
120-
trackPageView(): void {}
121+
trackPageView(_options?: TrackPageViewOptions): void {}
121122
track(_event: string, _properties?: Record<string, unknown>): void {}
122123
startSessionRecording(): void {}
123124
stopSessionRecording(): void {}

src/core/insights/datalayer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ export const track = (event: string, properties?: Record<string, unknown>) => {
1717
...properties,
1818
});
1919
};
20+
21+
export const trackPageView = () => {
22+
track("client-side-route-change");
23+
};

src/core/insights/index.test.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @vitest-environment jsdom
33
*/
44

5-
import { describe, expect, beforeEach, afterEach, it, vi } from "vitest";
5+
import { describe, expect, beforeEach, afterEach, it, vi, Mock } from "vitest";
66

77
import * as datalayer from "./datalayer";
88
import * as mixpanel from "./mixpanel";
@@ -13,6 +13,7 @@ import * as insights from "./index";
1313
// Mock the dependencies
1414
vi.mock("./datalayer", () => ({
1515
track: vi.fn(),
16+
trackPageView: vi.fn(),
1617
}));
1718

1819
vi.mock("./mixpanel", () => ({
@@ -90,6 +91,7 @@ describe("Insights Command Queue", () => {
9091
expect(posthog.identify).not.toHaveBeenCalled();
9192
expect(mixpanel.trackPageView).not.toHaveBeenCalled();
9293
expect(posthog.trackPageView).not.toHaveBeenCalled();
94+
expect(datalayer.trackPageView).not.toHaveBeenCalled();
9395

9496
// Now initialize
9597
insights.initInsights(testConfig);
@@ -122,11 +124,12 @@ describe("Insights Command Queue", () => {
122124

123125
expect(mixpanel.trackPageView).toHaveBeenCalled();
124126
expect(posthog.trackPageView).toHaveBeenCalled();
127+
expect(datalayer.trackPageView).not.toHaveBeenCalled();
125128
});
126129

127130
it("should handle errors in queued methods gracefully", async () => {
128131
// Setup an error for one of the methods
129-
mixpanel.track.mockImplementationOnce(() => {
132+
(mixpanel.track as Mock).mockImplementationOnce(() => {
130133
throw new Error("Mixpanel error");
131134
});
132135

@@ -152,6 +155,14 @@ describe("Insights Command Queue", () => {
152155
});
153156
expect(mixpanel.trackPageView).toHaveBeenCalled();
154157
expect(posthog.trackPageView).toHaveBeenCalled();
158+
expect(datalayer.trackPageView).not.toHaveBeenCalled();
159+
});
160+
161+
it("should report page view to GTM as well when includeDataLayer is true", () => {
162+
insights.trackPageView({ includeDataLayer: true });
163+
expect(mixpanel.trackPageView).toHaveBeenCalled();
164+
expect(posthog.trackPageView).toHaveBeenCalled();
165+
expect(datalayer.trackPageView).toHaveBeenCalled();
155166
});
156167
});
157168

@@ -188,6 +199,7 @@ describe("Insights Command Queue", () => {
188199
insights.trackPageView();
189200
expect(mixpanel.trackPageView).toHaveBeenCalled();
190201
expect(posthog.trackPageView).toHaveBeenCalled();
202+
expect(datalayer.trackPageView).not.toHaveBeenCalled();
191203

192204
insights.startSessionRecording();
193205
expect(mixpanel.startSessionRecording).toHaveBeenCalled();
@@ -205,6 +217,13 @@ describe("Insights Command Queue", () => {
205217
expect(mixpanel.disableDebugMode).toHaveBeenCalled();
206218
expect(posthog.disableDebugMode).toHaveBeenCalled();
207219
});
220+
221+
it("should report page view to GTM as well when includeDataLayer is true", () => {
222+
insights.trackPageView({ includeDataLayer: true });
223+
expect(mixpanel.trackPageView).toHaveBeenCalled();
224+
expect(posthog.trackPageView).toHaveBeenCalled();
225+
expect(datalayer.trackPageView).toHaveBeenCalled();
226+
});
208227
});
209228

210229
describe("Observer Setup", () => {
@@ -281,7 +300,7 @@ describe("Insights Command Queue", () => {
281300
describe("Error Handling", () => {
282301
it("should handle initialization errors gracefully", () => {
283302
// Setup an error in initialization
284-
mixpanel.initMixpanel.mockImplementationOnce(() => {
303+
(mixpanel.initMixpanel as Mock).mockImplementationOnce(() => {
285304
throw new Error("Mixpanel init error");
286305
});
287306

@@ -303,11 +322,11 @@ describe("Insights Command Queue", () => {
303322
vi.clearAllMocks();
304323

305324
// Setup errors in tracking
306-
mixpanel.track.mockImplementationOnce(() => {
325+
(mixpanel.track as Mock).mockImplementationOnce(() => {
307326
throw new Error("Mixpanel track error");
308327
});
309328

310-
posthog.track.mockImplementationOnce(() => {
329+
(posthog.track as Mock).mockImplementationOnce(() => {
311330
throw new Error("Posthog track error");
312331
});
313332

src/core/insights/index.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { InsightsConfig, InsightsIdentity } from "./types";
1+
import {
2+
InsightsConfig,
3+
InsightsIdentity,
4+
TrackPageViewOptions,
5+
} from "./types";
26
import { InsightsCommandQueue } from "./command-queue";
37
export type { InsightsConfig };
48

@@ -32,7 +36,8 @@ export const enableDebugMode = () => insights.enableDebugMode();
3236
export const disableDebugMode = () => insights.disableDebugMode();
3337
export const identify = (identity: InsightsIdentity) =>
3438
insights.identify(identity);
35-
export const trackPageView = () => insights.trackPageView();
39+
export const trackPageView = (options?: TrackPageViewOptions) =>
40+
insights.trackPageView(options);
3641
export const track = (event: string, properties?: Record<string, unknown>) =>
3742
insights.track(event, properties);
3843
export const startSessionRecording = () => insights.startSessionRecording();

src/core/insights/service.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type {
22
AnalyticsService,
33
InsightsConfig,
44
InsightsIdentity,
5+
TrackPageViewOptions,
56
} from "./types";
67
import * as datalayer from "./datalayer";
78
import * as mixpanel from "./mixpanel";
@@ -111,7 +112,7 @@ export class InsightsService implements AnalyticsService {
111112
}
112113
}
113114

114-
trackPageView(): void {
115+
trackPageView(options?: TrackPageViewOptions): void {
115116
if (this.debugMode) {
116117
logger.info("Tracking page view");
117118
}
@@ -131,6 +132,16 @@ export class InsightsService implements AnalyticsService {
131132
logger.error("Failed to track page view in Posthog", e);
132133
}
133134
}
135+
136+
if (options?.includeDataLayer) {
137+
try {
138+
datalayer.trackPageView();
139+
} catch (e) {
140+
if (this.debugMode) {
141+
logger.error("Failed to track page view in GTM", e);
142+
}
143+
}
144+
}
134145
}
135146

136147
track(event: string, properties?: Record<string, unknown>): void {

src/core/insights/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export interface AnalyticsService {
1313
enableDebugMode: () => void;
1414
disableDebugMode: () => void;
1515
identify: (identity: InsightsIdentity) => void;
16-
trackPageView: () => void;
16+
trackPageView: (options?: TrackPageViewOptions) => void;
1717
track: (event: string, properties?: Record<string, unknown>) => void;
1818
startSessionRecording: () => void;
1919
stopSessionRecording: () => void;
@@ -33,3 +33,7 @@ export type InsightsIdentity = {
3333
email?: string;
3434
name?: string;
3535
};
36+
37+
export type TrackPageViewOptions = {
38+
includeDataLayer?: boolean;
39+
};

0 commit comments

Comments
 (0)