unified-analytics
Version:
Unified analytics library for web applications
90 lines (89 loc) • 3.24 kB
JavaScript
/**
* 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();