From b298dbacb0701045d18a104fb40cbad1897f0fbb Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Wed, 23 Jul 2025 15:23:43 +0100 Subject: [PATCH] Add backend even tracking (#8946) * Add backend even tracking * Update src/lib/browser.ts Co-authored-by: Arik Chakma --------- Co-authored-by: Arik Chakma --- .astro/types.d.ts | 1 + src/components/Analytics/analytics.ts | 32 ++++++++++++++- src/lib/browser.ts | 57 +++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/.astro/types.d.ts b/.astro/types.d.ts index f964fe0cf..03d7cc43f 100644 --- a/.astro/types.d.ts +++ b/.astro/types.d.ts @@ -1 +1,2 @@ /// +/// \ No newline at end of file diff --git a/src/components/Analytics/analytics.ts b/src/components/Analytics/analytics.ts index 0d105033e..07a292f0c 100644 --- a/src/components/Analytics/analytics.ts +++ b/src/components/Analytics/analytics.ts @@ -1,4 +1,5 @@ import { httpPost } from '../../lib/query-http'; +import { getPageTrackingData } from '../../lib/browser'; declare global { interface Window { @@ -26,6 +27,7 @@ window.fireEvent = (props) => { const eventId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; if (['course', 'ai_tutor'].includes(category)) { + const trackingData = getPageTrackingData(); const url = new URL(import.meta.env.PUBLIC_API_URL); url.pathname = '/api/_t'; url.searchParams.set('action', action); @@ -34,7 +36,22 @@ window.fireEvent = (props) => { url.searchParams.set('value', value ?? ''); url.searchParams.set('event_id', eventId); - httpPost(url.toString(), {}).catch(console.error); + httpPost(url.toString(), { + page_location: trackingData.page_location, + page_path: trackingData.page_path, + page_referrer: trackingData.page_referrer, + page_title: trackingData.page_title, + user_agent: trackingData.user_agent, + screen_resolution: trackingData.screen_resolution, + viewport_size: trackingData.viewport_size, + session_id: trackingData.session_id, + gclid: trackingData.gclid, + utm_source: trackingData.utm_source, + utm_medium: trackingData.utm_medium, + utm_campaign: trackingData.utm_campaign, + utm_content: trackingData.utm_content, + utm_term: trackingData.utm_term, + }).catch(console.error); return; } @@ -50,12 +67,25 @@ window.fireEvent = (props) => { return; } + const trackingData = getPageTrackingData(); + window.gtag('event', action, { event_category: category, event_label: label, value: value, event_id: eventId, source: 'client', + page_location: trackingData.page_location, + page_path: trackingData.page_path, + page_referrer: trackingData.page_referrer, + page_title: trackingData.page_title, + session_id: trackingData.session_id, + gclid: trackingData.gclid, + utm_source: trackingData.utm_source, + utm_medium: trackingData.utm_medium, + utm_campaign: trackingData.utm_campaign, + utm_content: trackingData.utm_content, + utm_term: trackingData.utm_term, ...(callback ? { event_callback: callback } : {}), }); }; diff --git a/src/lib/browser.ts b/src/lib/browser.ts index 631410fe5..890e43003 100644 --- a/src/lib/browser.ts +++ b/src/lib/browser.ts @@ -176,3 +176,60 @@ export function setUrlParams(params: Record) { window.history.pushState(null, '', url.toString()); } } + +export function getGclid(): string | undefined { + if (typeof window === 'undefined') { + return undefined; + } + + const params = new URLSearchParams(window.location.search); + const gclid = params.get('gclid'); + + if (gclid) { + localStorage.setItem('gclid', gclid); + return gclid; + } + + return localStorage.getItem('gclid') || undefined; +} + +export function generateSessionId(): string { + if (typeof window === 'undefined') { + return ''; + } + + const existingSessionId = sessionStorage.getItem('session_id'); + if (existingSessionId) { + return existingSessionId; + } + + const sessionId = `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`; + sessionStorage.setItem('session_id', sessionId); + return sessionId; +} + +export function getPageTrackingData() { + if (typeof window === 'undefined') { + return {}; + } + + const utmParams = getUrlUtmParams(); + const storedUtmParams = getStoredUtmParams(); + + return { + page_location: window.location.href, + page_path: window.location.pathname, + page_referrer: document.referrer || undefined, + page_title: document.title, + user_agent: navigator?.userAgent || '', + screen_resolution: `${screen.width}x${screen.height}`, + viewport_size: `${window.innerWidth}x${window.innerHeight}`, + session_id: generateSessionId(), + gclid: getGclid(), + utm_source: utmParams.utmSource || storedUtmParams.utmSource, + utm_medium: utmParams.utmMedium || storedUtmParams.utmMedium, + utm_campaign: utmParams.utmCampaign || storedUtmParams.utmCampaign, + utm_content: utmParams.utmContent || storedUtmParams.utmContent, + utm_term: utmParams.utmTerm || storedUtmParams.utmTerm, + }; +}