UNPKG

unified-analytics

Version:

Unified analytics library for web applications

90 lines (89 loc) 3.24 kB
/** * Google Analytics 4 service implementation using gtag.js */ export class GoogleAnalytics4Service { constructor() { this._initialized = false; this._debug = false; } /** * Get the measurement ID for this GA4 instance */ getInstance() { return this._measurementId; } /** * Initialize Google Analytics 4 with the provided measurement ID * @param options - Configuration options for GA4 */ init(options) { if (this._initialized) { console.warn("[GoogleAnalytics4Service] Already initialized"); return; } this._measurementId = options.measurementId; this._debug = options.debug || false; this._config = options.config; this._loadGtagScript(options.measurementId, options.config); this._initialized = true; } /** * Track an event in Google Analytics 4 * @param event - The event to track * @param debug - Whether to log debug information */ onEvent(event, debug) { const shouldDebug = debug || this._debug; if (shouldDebug) { console.log("[GoogleAnalytics4Service] Debug Event:", event); } if (!this._initialized || !this._measurementId) { throw new Error("Google Analytics 4 not initialized"); } window.gtag("event", event.name, { ...event.attributes, send_to: this._measurementId, }); } /** * Create a new instance of GoogleAnalytics4Service * @returns A new GoogleAnalytics4Service instance */ clone() { const clonedService = new GoogleAnalytics4Service(); return clonedService; } /** * Load the gtag.js script and initialize with the provided measurement ID * @param measurementId - The GA4 measurement ID * @param config - Optional configuration parameters */ _loadGtagScript(measurementId, config) { // Skip if running in a non-browser environment if (typeof window === "undefined" || typeof document === "undefined") { return; } // Check if the GA4 script with this measurement ID already exists const isScriptAlreadyExists = !!document.querySelector(`script[src*="gtag/js?id=${measurementId}"]`); // Initialize dataLayer array if it doesn't exist window.dataLayer = window.dataLayer || []; // Define the gtag function if it doesn't exist if (!window.gtag) { window.gtag = function () { // eslint-disable-next-line prefer-rest-params window.dataLayer.push(arguments); }; } // Initialize the gtag with timestamp first window.gtag("js", new Date()); // Configure the measurement ID window.gtag("config", measurementId, config || {}); if (!isScriptAlreadyExists) { const script = document.createElement("script"); script.async = true; script.src = `https://www.googletagmanager.com/gtag/js?id=${measurementId}`; document.head.appendChild(script); } } } export const googleAnalytics4Service = new GoogleAnalytics4Service();