mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
web: Attempt at compliant, cookie-less anonymous tracking for the website (#8957)
This commit is contained in:
parent
416fa5727e
commit
eb68c65296
3 changed files with 52 additions and 45 deletions
|
|
@ -5,7 +5,7 @@ import ReactCookieConsent from "react-cookie-consent"
|
|||
import { Cookie } from "lucide-react"
|
||||
import { getDomain } from "tldts"
|
||||
import { CONSENT_COOKIE_NAME } from "@roo-code/types"
|
||||
import { dispatchConsentEvent } from "@/lib/analytics/consent-manager"
|
||||
import { handleConsentAccept, handleConsentReject } from "@/lib/analytics/consent-manager"
|
||||
|
||||
/**
|
||||
* GDPR-compliant cookie consent banner component
|
||||
|
|
@ -23,11 +23,11 @@ export function CookieConsentWrapper() {
|
|||
}, [])
|
||||
|
||||
const handleAccept = () => {
|
||||
dispatchConsentEvent(true)
|
||||
handleConsentAccept()
|
||||
}
|
||||
|
||||
const handleDecline = () => {
|
||||
dispatchConsentEvent(false)
|
||||
handleConsentReject()
|
||||
}
|
||||
|
||||
const extraCookieOptions = cookieDomain
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
import { usePathname, useSearchParams } from "next/navigation"
|
||||
import posthog from "posthog-js"
|
||||
import { PostHogProvider as OriginalPostHogProvider } from "posthog-js/react"
|
||||
import { useEffect, Suspense, useState } from "react"
|
||||
import { hasConsent, onConsentChange } from "@/lib/analytics/consent-manager"
|
||||
import { useEffect, Suspense } from "react"
|
||||
import { hasConsent } from "@/lib/analytics/consent-manager"
|
||||
|
||||
function PageViewTracker() {
|
||||
const pathname = usePathname()
|
||||
|
|
@ -28,11 +28,9 @@ function PageViewTracker() {
|
|||
}
|
||||
|
||||
export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
||||
const [isInitialized, setIsInitialized] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
// Initialize PostHog only on the client side AND when consent is given
|
||||
if (typeof window !== "undefined") {
|
||||
// Initialize PostHog immediately on the client side
|
||||
if (typeof window !== "undefined" && !posthog.__loaded) {
|
||||
const posthogKey = process.env.NEXT_PUBLIC_POSTHOG_KEY
|
||||
const posthogHost = process.env.NEXT_PUBLIC_POSTHOG_HOST
|
||||
|
||||
|
|
@ -52,48 +50,32 @@ export function PostHogProvider({ children }: { children: React.ReactNode }) {
|
|||
)
|
||||
}
|
||||
|
||||
const initializePosthog = () => {
|
||||
if (!isInitialized) {
|
||||
posthog.init(posthogKey, {
|
||||
api_host: posthogHost || "https://us.i.posthog.com",
|
||||
capture_pageview: false,
|
||||
loaded: (posthogInstance) => {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
posthogInstance.debug()
|
||||
}
|
||||
},
|
||||
respect_dnt: true, // Respect Do Not Track
|
||||
})
|
||||
setIsInitialized(true)
|
||||
}
|
||||
}
|
||||
// Check if user has already consented to cookies
|
||||
const userHasConsented = hasConsent()
|
||||
|
||||
// Check initial consent status
|
||||
if (hasConsent()) {
|
||||
initializePosthog()
|
||||
}
|
||||
|
||||
// Listen for consent changes
|
||||
const unsubscribe = onConsentChange((consented) => {
|
||||
if (consented && !isInitialized) {
|
||||
initializePosthog()
|
||||
}
|
||||
// Initialize PostHog with appropriate persistence based on consent
|
||||
posthog.init(posthogKey, {
|
||||
api_host: posthogHost || "https://us.i.posthog.com",
|
||||
capture_pageview: false, // We handle pageview tracking manually
|
||||
loaded: (posthogInstance) => {
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
posthogInstance.debug()
|
||||
}
|
||||
},
|
||||
save_referrer: true, // Save referrer information
|
||||
save_campaign_params: true, // Save UTM parameters
|
||||
respect_dnt: true, // Respect Do Not Track
|
||||
persistence: userHasConsented ? "localStorage+cookie" : "memory", // Use localStorage if consented, otherwise memory-only
|
||||
opt_out_capturing_by_default: false, // Start tracking immediately
|
||||
})
|
||||
|
||||
return () => {
|
||||
unsubscribe()
|
||||
}
|
||||
}
|
||||
}, [isInitialized])
|
||||
}, [])
|
||||
|
||||
// Only provide PostHog context if it's initialized
|
||||
return (
|
||||
<OriginalPostHogProvider client={posthog}>
|
||||
{isInitialized && (
|
||||
<Suspense fallback={null}>
|
||||
<PageViewTracker />
|
||||
</Suspense>
|
||||
)}
|
||||
<Suspense fallback={null}>
|
||||
<PageViewTracker />
|
||||
</Suspense>
|
||||
{children}
|
||||
</OriginalPostHogProvider>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import { getCookieConsentValue } from "react-cookie-consent"
|
||||
import { CONSENT_COOKIE_NAME } from "@roo-code/types"
|
||||
import posthog from "posthog-js"
|
||||
|
||||
export const CONSENT_EVENT = "cookieConsentChanged"
|
||||
|
||||
|
|
@ -45,3 +46,27 @@ export function onConsentChange(callback: (consented: boolean) => void): () => v
|
|||
window.addEventListener(CONSENT_EVENT, handler)
|
||||
return () => window.removeEventListener(CONSENT_EVENT, handler)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle user accepting cookies
|
||||
* Opts PostHog back into cookie-based tracking
|
||||
*/
|
||||
export function handleConsentAccept(): void {
|
||||
if (typeof window !== "undefined" && posthog.__loaded) {
|
||||
// User accepted - ensure localStorage+cookie persistence is enabled
|
||||
posthog.opt_in_capturing()
|
||||
posthog.set_config({
|
||||
persistence: "localStorage+cookie",
|
||||
})
|
||||
}
|
||||
dispatchConsentEvent(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle user rejecting cookies
|
||||
* Switches PostHog to cookieless (memory-only) mode
|
||||
*/
|
||||
export function handleConsentReject(): void {
|
||||
// User rejected - stick to cookieless mode
|
||||
dispatchConsentEvent(false)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue