105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState, useRef } from 'react';
|
|
import { usePathname, useSearchParams } from 'next/navigation';
|
|
import posthog from 'posthog-js';
|
|
|
|
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
|
const pathname = usePathname();
|
|
const searchParams = useSearchParams();
|
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
const initializationAttempted = useRef(false);
|
|
|
|
// Initialize PostHog once
|
|
useEffect(() => {
|
|
// Prevent double initialization in React Strict Mode
|
|
if (initializationAttempted.current) return;
|
|
initializationAttempted.current = true;
|
|
|
|
const cookieConsent = localStorage.getItem('cookieConsent');
|
|
|
|
if (cookieConsent === 'accepted') {
|
|
const apiKey = process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
|
const apiHost = process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
|
|
|
if (!apiKey) {
|
|
console.warn('PostHog API key not configured');
|
|
return;
|
|
}
|
|
|
|
// Check if already initialized (using _loaded property)
|
|
if (!(posthog as any)._loaded) {
|
|
posthog.init(apiKey, {
|
|
api_host: apiHost || 'https://us.i.posthog.com',
|
|
person_profiles: 'identified_only',
|
|
capture_pageview: false, // Manual pageview tracking
|
|
capture_pageleave: true,
|
|
autocapture: true,
|
|
respect_dnt: true,
|
|
opt_out_capturing_by_default: false,
|
|
});
|
|
|
|
// Enable debug mode in development
|
|
if (process.env.NODE_ENV === 'development') {
|
|
posthog.debug();
|
|
}
|
|
|
|
// Set initialized immediately after init
|
|
setIsInitialized(true);
|
|
} else {
|
|
setIsInitialized(true); // Already loaded
|
|
}
|
|
}
|
|
|
|
// NO cleanup function - PostHog should persist across page navigation
|
|
}, []);
|
|
|
|
// Track page views ONLY after PostHog is initialized
|
|
useEffect(() => {
|
|
const cookieConsent = localStorage.getItem('cookieConsent');
|
|
|
|
if (cookieConsent === 'accepted' && pathname && isInitialized) {
|
|
let url = window.origin + pathname;
|
|
if (searchParams && searchParams.toString()) {
|
|
url = url + `?${searchParams.toString()}`;
|
|
}
|
|
|
|
posthog.capture('$pageview', {
|
|
$current_url: url,
|
|
});
|
|
}
|
|
}, [pathname, searchParams, isInitialized]); // Added isInitialized dependency
|
|
|
|
return <>{children}</>;
|
|
}
|
|
|
|
/**
|
|
* Helper function to identify user after login
|
|
*/
|
|
export function identifyUser(userId: string, traits?: Record<string, any>) {
|
|
const cookieConsent = localStorage.getItem('cookieConsent');
|
|
if (cookieConsent === 'accepted' && (posthog as any)._loaded) {
|
|
posthog.identify(userId, traits);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper function to track custom events
|
|
*/
|
|
export function trackEvent(eventName: string, properties?: Record<string, any>) {
|
|
const cookieConsent = localStorage.getItem('cookieConsent');
|
|
if (cookieConsent === 'accepted' && (posthog as any)._loaded) {
|
|
posthog.capture(eventName, properties);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper function to reset user on logout
|
|
*/
|
|
export function resetUser() {
|
|
const cookieConsent = localStorage.getItem('cookieConsent');
|
|
if (cookieConsent === 'accepted' && (posthog as any)._loaded) {
|
|
posthog.reset();
|
|
}
|
|
}
|