|
2 | 2 | * Analytics Utility Module for GA4 Event Tracking |
3 | 3 | * |
4 | 4 | * This module provides type-safe helper functions for sending GA4 events. |
5 | | - * It handles Partytown's async nature and provides debug mode for development. |
| 5 | + * It uses the global gtag() function which runs in the main thread. |
6 | 6 | * |
7 | 7 | * @module analytics |
8 | 8 | */ |
9 | 9 |
|
10 | | -// Type for gtag function (loaded by Google Tag Manager via Partytown) |
11 | | -type GtagFunction = ( |
12 | | - command: string, |
13 | | - eventNameOrConfig: string, |
14 | | - params?: Record<string, unknown>, |
15 | | -) => void |
16 | | - |
17 | 10 | // ============================================================================ |
18 | 11 | // Types & Interfaces |
19 | 12 | // ============================================================================ |
@@ -198,36 +191,41 @@ function debugLog<T extends Record<string, unknown>>( |
198 | 191 | // Core Tracking Function |
199 | 192 | // ============================================================================ |
200 | 193 |
|
| 194 | +// Extend Window interface for gtag |
| 195 | +declare global { |
| 196 | + interface Window { |
| 197 | + gtag?: (...args: unknown[]) => void |
| 198 | + } |
| 199 | +} |
| 200 | + |
201 | 201 | /** |
202 | | - * Safely get the gtag function, handling Partytown's async loading |
| 202 | + * Get the gtag function from the window object |
203 | 203 | */ |
204 | | -function getGtag(): GtagFunction | null { |
| 204 | +function getGtag(): ((...args: unknown[]) => void) | null { |
205 | 205 | if (typeof window === 'undefined') return null |
206 | | - // gtag is loaded via Partytown, may not be immediately available |
207 | | - return (window as unknown as { gtag?: GtagFunction }).gtag ?? null |
| 206 | + return window.gtag ?? null |
208 | 207 | } |
209 | 208 |
|
210 | 209 | /** |
211 | 210 | * Generic event tracking function |
212 | | - * Handles cases where gtag might not be loaded yet (Partytown delay) |
| 211 | + * Uses the global gtag() function directly for event tracking. |
213 | 212 | */ |
214 | 213 | export function trackEvent<T extends Record<string, unknown>>( |
215 | 214 | eventName: string, |
216 | 215 | params: T, |
217 | 216 | ): void { |
218 | 217 | debugLog(eventName, params) |
219 | 218 |
|
220 | | - const gtagFn = getGtag() |
221 | | - if (gtagFn) { |
222 | | - gtagFn('event', eventName, params) |
| 219 | + const gtag = getGtag() |
| 220 | + if (gtag) { |
| 221 | + gtag('event', eventName, params) |
223 | 222 | } else { |
224 | | - // If gtag not ready, queue the event for when it becomes available |
225 | | - // This is a fallback for slow Partytown initialization |
| 223 | + // If gtag not ready, queue the event with retry |
226 | 224 | let timeoutId: ReturnType<typeof setTimeout> | null = null |
227 | 225 | const checkInterval = setInterval(() => { |
228 | | - const fn = getGtag() |
229 | | - if (fn) { |
230 | | - fn('event', eventName, params) |
| 226 | + const g = getGtag() |
| 227 | + if (g) { |
| 228 | + g('event', eventName, params) |
231 | 229 | clearInterval(checkInterval) |
232 | 230 | if (timeoutId) clearTimeout(timeoutId) |
233 | 231 | } |
|
0 commit comments