140 lines
3.1 KiB
TypeScript
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);
|
|
};
|