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,
+ };
+}