Capture any deferred navigate events before the page unloads

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2023-06-05 16:25:52 +02:00
parent 34f54060f2
commit a164e4eac4
@@ -39,6 +39,11 @@ type TempGlobalEvents = {
mostRecentRoutableExtensionRender?: {
context: AnalyticsContextValue;
};
/**
* Tracks whether or not a beforeunload event listener has already been
* registered.
*/
beforeUnloadRegistered: boolean;
};
/**
@@ -50,6 +55,7 @@ const globalEvents = getOrCreateGlobalSingleton<TempGlobalEvents>(
() => ({
mostRecentGatheredNavigation: undefined,
mostRecentRoutableExtensionRender: undefined,
beforeUnloadRegistered: false,
}),
);
@@ -66,7 +72,30 @@ export class Tracker implements AnalyticsTracker {
pluginId: 'root',
extension: 'App',
},
) {}
) {
// Only register a single beforeunload event across all trackers.
if (!globalEvents.beforeUnloadRegistered) {
// Before the page unloads, attempt to capture any deferred navigation
// events that haven't yet been captured.
addEventListener(
'beforeunload',
() => {
if (globalEvents.mostRecentGatheredNavigation) {
this.analyticsApi.captureEvent({
...globalEvents.mostRecentGatheredNavigation,
...globalEvents.mostRecentRoutableExtensionRender,
});
globalEvents.mostRecentGatheredNavigation = undefined;
globalEvents.mostRecentRoutableExtensionRender = undefined;
}
},
{ once: true, passive: true },
);
// Prevent duplicate handlers from being registered.
globalEvents.beforeUnloadRegistered = true;
}
}
setContext(context: AnalyticsContextValue) {
this.context = context;