From 60f5c439a668d3f4a54130eeed466d99412f7db4 Mon Sep 17 00:00:00 2001 From: Omer Katzir Date: Sun, 4 Jan 2026 18:10:33 +0200 Subject: [PATCH 1/5] Analytics | referrer built-in event --- src/modules/analytics.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/modules/analytics.ts b/src/modules/analytics.ts index 0a32a90..90d8aa9 100644 --- a/src/modules/analytics.ts +++ b/src/modules/analytics.ts @@ -13,6 +13,7 @@ import type { AuthModule } from "./auth.types"; import { generateUuid } from "../utils/common"; export const USER_HEARTBEAT_EVENT_NAME = "__user_heartbeat_event__"; +export const ANALYTICS_REFERRER_EVENT_NAME = "__referrer_event__"; export const ANALYTICS_CONFIG_ENABLE_URL_PARAM_KEY = "analytics-enable"; export const ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY = @@ -39,6 +40,7 @@ const analyticsSharedState = getSharedInstance( requestsQueue: [] as TrackEventData[], isProcessing: false, isHeartBeatProcessing: false, + wasReferrerTracked: false, sessionContext: null as SessionContext | null, config: { ...defaultConfiguration, @@ -174,6 +176,8 @@ export const createAnalyticsModule = ({ startProcessing(); // start the heart beat processor // clearHeartBeatProcessor = startHeartBeatProcessor(track); + // track the referrer event // + trackReferrerEvent(track); // start the visibility change listener // if (typeof window !== "undefined") { window.addEventListener("visibilitychange", onVisibilityChange); @@ -233,6 +237,15 @@ function startHeartBeatProcessor(track: (params: TrackEventParams) => void) { }; } +function trackReferrerEvent(track: (params: TrackEventParams) => void) { + if (typeof window === "undefined" || analyticsSharedState.wasReferrerTracked) + return; + analyticsSharedState.wasReferrerTracked = true; + const referrer = document.referrer; + if (!referrer) return; + track({ eventName: ANALYTICS_REFERRER_EVENT_NAME, properties: { referrer } }); +} + function getEventIntrinsicData(): TrackEventIntrinsicData { return { timestamp: new Date().toISOString(), From f3ece835d783fcd93d303215bc1746c18c679f9a Mon Sep 17 00:00:00 2001 From: Omer Katzir Date: Sun, 4 Jan 2026 19:32:29 +0200 Subject: [PATCH 2/5] null check --- src/modules/analytics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/analytics.ts b/src/modules/analytics.ts index f4f8e95..b782255 100644 --- a/src/modules/analytics.ts +++ b/src/modules/analytics.ts @@ -241,7 +241,7 @@ function trackReferrerEvent(track: (params: TrackEventParams) => void) { if (typeof window === "undefined" || analyticsSharedState.wasReferrerTracked) return; analyticsSharedState.wasReferrerTracked = true; - const referrer = document.referrer; + const referrer = document?.referrer; if (!referrer) return; track({ eventName: ANALYTICS_REFERRER_EVENT_NAME, properties: { referrer } }); } From 2cf82395b1dc717169fc1d082b1bdc16d1ae8858 Mon Sep 17 00:00:00 2001 From: Omer Katzir Date: Sun, 4 Jan 2026 21:49:12 +0200 Subject: [PATCH 3/5] session duration event --- src/modules/analytics.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/modules/analytics.ts b/src/modules/analytics.ts index b782255..b76e9cd 100644 --- a/src/modules/analytics.ts +++ b/src/modules/analytics.ts @@ -14,6 +14,8 @@ import { generateUuid } from "../utils/common.js"; export const USER_HEARTBEAT_EVENT_NAME = "__user_heartbeat_event__"; export const ANALYTICS_REFERRER_EVENT_NAME = "__referrer_event__"; +export const ANALYTICS_SESSION_DURATION_EVENT_NAME = + "__session_duration_event__"; export const ANALYTICS_CONFIG_ENABLE_URL_PARAM_KEY = "analytics-enable"; export const ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY = @@ -42,6 +44,7 @@ const analyticsSharedState = getSharedInstance( isHeartBeatProcessing: false, wasReferrerTracked: false, sessionContext: null as SessionContext | null, + sessionStartTime: null as string | null, config: { ...defaultConfiguration, ...getAnalyticsConfigFromUrlParams(), @@ -145,11 +148,14 @@ export const createAnalyticsModule = ({ batchSize, }); clearHeartBeatProcessor = startHeartBeatProcessor(track); + setSessionDurationTimerStart(); }; const onDocHidden = () => { stopAnalyticsProcessor(); clearHeartBeatProcessor?.(); + trackSessionDurationEvent(track); + // flush entire queue on visibility change and hope for the best // const eventsData = analyticsSharedState.requestsQueue.splice(0); flush(eventsData, { isBeacon: true }); @@ -246,6 +252,31 @@ function trackReferrerEvent(track: (params: TrackEventParams) => void) { track({ eventName: ANALYTICS_REFERRER_EVENT_NAME, properties: { referrer } }); } +function setSessionDurationTimerStart() { + if ( + typeof window === "undefined" || + analyticsSharedState.sessionStartTime !== null + ) { + return; + } + analyticsSharedState.sessionStartTime = new Date().toISOString(); +} +function trackSessionDurationEvent(track: (params: TrackEventParams) => void) { + if ( + typeof window === "undefined" || + analyticsSharedState.sessionStartTime === null + ) + return; + const sessionDuration = + new Date().getTime() - + new Date(analyticsSharedState.sessionStartTime).getTime(); + analyticsSharedState.sessionStartTime = null; + track({ + eventName: ANALYTICS_SESSION_DURATION_EVENT_NAME, + properties: { sessionDuration }, + }); +} + function getEventIntrinsicData(): TrackEventIntrinsicData { return { timestamp: new Date().toISOString(), From 0851053c0ce6480a6ee4066182ec6211dd47f002 Mon Sep 17 00:00:00 2001 From: Omer Katzir Date: Tue, 6 Jan 2026 13:37:12 +0200 Subject: [PATCH 4/5] initialization event --- src/modules/analytics.ts | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/modules/analytics.ts b/src/modules/analytics.ts index b76e9cd..0279dc7 100644 --- a/src/modules/analytics.ts +++ b/src/modules/analytics.ts @@ -13,7 +13,7 @@ import type { AuthModule } from "./auth.types"; import { generateUuid } from "../utils/common.js"; export const USER_HEARTBEAT_EVENT_NAME = "__user_heartbeat_event__"; -export const ANALYTICS_REFERRER_EVENT_NAME = "__referrer_event__"; +export const ANALYTICS_INITIALIZTION_EVENT_NAME = "__initialization_event__"; export const ANALYTICS_SESSION_DURATION_EVENT_NAME = "__session_duration_event__"; export const ANALYTICS_CONFIG_ENABLE_URL_PARAM_KEY = "analytics-enable"; @@ -42,7 +42,7 @@ const analyticsSharedState = getSharedInstance( requestsQueue: [] as TrackEventData[], isProcessing: false, isHeartBeatProcessing: false, - wasReferrerTracked: false, + wasInitializationTracked: false, sessionContext: null as SessionContext | null, sessionStartTime: null as string | null, config: { @@ -183,7 +183,7 @@ export const createAnalyticsModule = ({ // start the heart beat processor // clearHeartBeatProcessor = startHeartBeatProcessor(track); // track the referrer event // - trackReferrerEvent(track); + trackInitializationEvent(track); // start the visibility change listener // if (typeof window !== "undefined") { window.addEventListener("visibilitychange", onVisibilityChange); @@ -243,13 +243,19 @@ function startHeartBeatProcessor(track: (params: TrackEventParams) => void) { }; } -function trackReferrerEvent(track: (params: TrackEventParams) => void) { - if (typeof window === "undefined" || analyticsSharedState.wasReferrerTracked) +function trackInitializationEvent(track: (params: TrackEventParams) => void) { + if ( + typeof window === "undefined" || + analyticsSharedState.wasInitializationTracked + ) return; - analyticsSharedState.wasReferrerTracked = true; - const referrer = document?.referrer; - if (!referrer) return; - track({ eventName: ANALYTICS_REFERRER_EVENT_NAME, properties: { referrer } }); + analyticsSharedState.wasInitializationTracked = true; + track({ + eventName: ANALYTICS_INITIALIZTION_EVENT_NAME, + properties: { + referrer: document?.referrer, + }, + }); } function setSessionDurationTimerStart() { From e849029842dc89ce2191d236ae59dd0ba28057a2 Mon Sep 17 00:00:00 2001 From: Omer Katzir Date: Tue, 6 Jan 2026 15:50:07 +0200 Subject: [PATCH 5/5] typo --- src/modules/analytics.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/analytics.ts b/src/modules/analytics.ts index 0279dc7..c63cdb4 100644 --- a/src/modules/analytics.ts +++ b/src/modules/analytics.ts @@ -13,7 +13,7 @@ import type { AuthModule } from "./auth.types"; import { generateUuid } from "../utils/common.js"; export const USER_HEARTBEAT_EVENT_NAME = "__user_heartbeat_event__"; -export const ANALYTICS_INITIALIZTION_EVENT_NAME = "__initialization_event__"; +export const ANALYTICS_INITIALIZATION_EVENT_NAME = "__initialization_event__"; export const ANALYTICS_SESSION_DURATION_EVENT_NAME = "__session_duration_event__"; export const ANALYTICS_CONFIG_ENABLE_URL_PARAM_KEY = "analytics-enable"; @@ -247,11 +247,13 @@ function trackInitializationEvent(track: (params: TrackEventParams) => void) { if ( typeof window === "undefined" || analyticsSharedState.wasInitializationTracked - ) + ) { return; + } + analyticsSharedState.wasInitializationTracked = true; track({ - eventName: ANALYTICS_INITIALIZTION_EVENT_NAME, + eventName: ANALYTICS_INITIALIZATION_EVENT_NAME, properties: { referrer: document?.referrer, },