Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions apps/web-roo-code/src/components/CookieConsentWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -23,11 +23,11 @@ export function CookieConsentWrapper() {
}, [])

const handleAccept = () => {
dispatchConsentEvent(true)
handleConsentAccept()
}

const handleDecline = () => {
dispatchConsentEvent(false)
handleConsentReject()
}

const extraCookieOptions = cookieDomain
Expand Down
64 changes: 21 additions & 43 deletions apps/web-roo-code/src/components/providers/posthog-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
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"

function PageViewTracker() {
const pathname = usePathname()
Expand All @@ -28,11 +27,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

Expand All @@ -52,48 +49,29 @@ 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 initial consent status
if (hasConsent()) {
initializePosthog()
}

// Listen for consent changes
const unsubscribe = onConsentChange((consented) => {
if (consented && !isInitialized) {
initializePosthog()
}
// Initialize PostHog with cookieless mode support
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: "memory", // Default persistence with cookies
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>
)
Expand Down
25 changes: 25 additions & 0 deletions apps/web-roo-code/src/lib/analytics/consent-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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 cookie tracking 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)
}