neuer versuch
This commit is contained in:
@@ -4,10 +4,30 @@ import { useEffect, useState, useRef } from 'react';
|
||||
import { usePathname, useSearchParams } from 'next/navigation';
|
||||
import posthog from 'posthog-js';
|
||||
|
||||
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
||||
export function PostHogPageView() {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
|
||||
// Track page views
|
||||
useEffect(() => {
|
||||
const cookieConsent = localStorage.getItem('cookieConsent');
|
||||
|
||||
if (cookieConsent === 'accepted' && pathname) {
|
||||
let url = window.origin + pathname;
|
||||
if (searchParams && searchParams.toString()) {
|
||||
url = url + `?${searchParams.toString()}`;
|
||||
}
|
||||
|
||||
posthog.capture('$pageview', {
|
||||
$current_url: url,
|
||||
});
|
||||
}
|
||||
}, [pathname, searchParams]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
||||
const initializationAttempted = useRef(false);
|
||||
|
||||
// Initialize PostHog once
|
||||
@@ -18,6 +38,9 @@ export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
const cookieConsent = localStorage.getItem('cookieConsent');
|
||||
|
||||
// Check if we should initialize based on consent
|
||||
// If not accepted yet, we don't init. CookieBanner deals with setting 'accepted' and reloading or calling init.
|
||||
// Ideally we should listen to consent changes, but for now matching previous behavior.
|
||||
if (cookieConsent === 'accepted') {
|
||||
const apiKey = process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
||||
const apiHost = process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
||||
@@ -27,49 +50,24 @@ export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
||||
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_pageview: false, // We handle this manually
|
||||
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}</>;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
import { Suspense } from 'react';
|
||||
import { ToastContainer } from '@/components/ui/Toast';
|
||||
import AuthProvider from '@/components/SessionProvider';
|
||||
import { PostHogProvider } from '@/components/PostHogProvider';
|
||||
import { PostHogProvider, PostHogPageView } from '@/components/PostHogProvider';
|
||||
import CookieBanner from '@/components/CookieBanner';
|
||||
|
||||
export function Providers({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
<PostHogProvider>
|
||||
<AuthProvider>
|
||||
{children}
|
||||
</AuthProvider>
|
||||
<CookieBanner />
|
||||
<ToastContainer />
|
||||
</PostHogProvider>
|
||||
</Suspense>
|
||||
<PostHogProvider>
|
||||
<Suspense fallback={null}>
|
||||
<PostHogPageView />
|
||||
</Suspense>
|
||||
<AuthProvider>
|
||||
{children}
|
||||
</AuthProvider>
|
||||
<CookieBanner />
|
||||
<ToastContainer />
|
||||
</PostHogProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
|
||||
<div className="grid md:grid-cols-4 gap-8">
|
||||
<div>
|
||||
<Link href="/" className="flex items-center space-x-2 mb-4 hover:opacity-80 transition-opacity">
|
||||
<img src="/logo.svg" alt="" className="w-10 h-10" />
|
||||
<img src="/logo.svg" alt="QR Master Logo" className="w-10 h-10" />
|
||||
<span className={`text-xl font-bold ${isDashboard ? 'text-gray-900' : ''}`}>QR Master</span>
|
||||
</Link>
|
||||
<p className={isDashboard ? 'text-gray-500' : 'text-gray-400'}>
|
||||
@@ -30,6 +30,7 @@ export function Footer({ variant = 'marketing', t }: FooterProps) {
|
||||
<ul className={`space-y-2 ${isDashboard ? 'text-gray-500' : 'text-gray-400'}`}>
|
||||
<li><Link href="/#features" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.features}</Link></li>
|
||||
<li><Link href="/#pricing" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.pricing}</Link></li>
|
||||
<li><Link href="/qr-code-tracking" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>QR Analytics</Link></li>
|
||||
<li><Link href="/faq" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.faq}</Link></li>
|
||||
<li><Link href="/blog" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>{translations.blog}</Link></li>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user