Files
FrenoCorp/src/lib/analytics/ga4-service.ts

140 lines
3.1 KiB
TypeScript

import { loadGA4 } from "./ga4-loader";
type GA4Event =
| "session_start"
| "page_view"
| "scroll"
| "click"
| "user_signup"
| "user_login"
| "user_logout"
| "project_create"
| "project_update"
| "project_delete"
| "screenplay_create"
| "screenplay_update"
| "screenplay_export"
| "begin_checkout"
| "add_to_cart"
| "add_to_wishlist"
| "view_item"
| "view_item_list"
| "select_item"
| "purchase"
| "refund"
| "sign_up"
| "lead"
| "search";
export interface GA4Config {
measurementId: string;
apiSecret?: string;
streamId?: string;
options?: {
debug?: boolean;
autoTrackPageViews?: boolean;
autoTrackScrolls?: boolean;
autoTrackOutboundLinks?: boolean;
};
}
export interface GA4EcommerceItem {
item_id: string;
item_name: string;
item_category?: string;
price: number;
quantity: number;
currency?: string;
}
export interface GA4PurchaseEvent {
transaction_id: string;
value: number;
currency: string;
tax?: number;
shipping?: number;
items: GA4EcommerceItem[];
}
export class GA4Service {
private measurementId: string;
private config: GA4Config;
private initialized: boolean = false;
constructor(config: GA4Config) {
this.measurementId = config.measurementId;
this.config = config;
}
async initialize(): Promise<void> {
await loadGA4(this.measurementId, this.config.options);
this.initialized = true;
}
track(event: GA4Event, params?: Record<string, unknown>): void {
if (!this.initialized) {
console.warn("GA4 not initialized");
return;
}
(window as any).gtag?.("event", event, params);
}
trackPageView(pageLocation?: string, pagePath?: string): void {
this.track("page_view", {
page_location: pageLocation || window.location.href,
page_path: pagePath || window.location.pathname,
page_title: document.title,
});
}
trackEcommerce(event: "purchase" | "refund", data: GA4PurchaseEvent): void {
this.track(event, {
transaction_id: data.transaction_id,
value: data.value,
currency: data.currency,
tax: data.tax,
shipping: data.shipping,
items: data.items,
});
}
trackAddToCart(item: GA4EcommerceItem): void {
this.track("add_to_cart", {
items: [item],
});
}
trackBeginCheckout(items: GA4EcommerceItem[], value: number): void {
this.track("begin_checkout", {
items,
value,
currency: items[0]?.currency || "USD",
});
}
trackViewItemList(items: GA4EcommerceItem[], itemListName: string): void {
this.track("view_item_list", {
items,
item_list_name: itemListName,
});
}
trackSelectItem(item: GA4EcommerceItem, itemListName: string): void {
this.track("select_item", {
items: [item],
item_list_name: itemListName,
});
}
setUserProperty(userId: string, userProperties?: Record<string, string>): void {
(window as any).gtag?.("set", "user_properties", {
user_id: userId,
...userProperties,
});
}
}
export const createGA4Service = (config: GA4Config): GA4Service => {
return new GA4Service(config);
};