Skip to content

Commit cbc30ab

Browse files
committed
fix: posthog accept
1 parent 77226f1 commit cbc30ab

1 file changed

Lines changed: 39 additions & 74 deletions

File tree

Lines changed: 39 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,51 @@
1-
import { defineNuxtPlugin } from '#app'
21
import posthog from 'posthog-js'
32

4-
type ConsentPayload = {
5-
// common shape: { categories: { necessary: true, analytics: false, ... } }
6-
categories?: Record<string, boolean>
7-
// some configs use "services"
8-
services?: Record<string, boolean>
9-
// some store directly as { analytics: true }
10-
[k: string]: any
11-
}
12-
13-
function hasAnalyticsConsent(raw: string | undefined, analyticsKey = 'analytics') {
14-
if (!raw) return false
15-
16-
try {
17-
const parsed: ConsentPayload = JSON.parse(raw)
18-
19-
if (typeof parsed[analyticsKey] === 'boolean') return parsed[analyticsKey]
20-
if (parsed.categories && typeof parsed.categories[analyticsKey] === 'boolean') return parsed.categories[analyticsKey]
21-
if (parsed.services && typeof parsed.services[analyticsKey] === 'boolean') return parsed.services[analyticsKey]
22-
23-
return false
24-
} catch {
25-
// if it’s not JSON, treat as no consent
26-
return false
3+
export default defineNuxtPlugin((nuxtApp) => {
4+
// 1) Init PostHog in a safe mode first (no cookies until consent)
5+
posthog.init(useRuntimeConfig().public.posthogKey, {
6+
api_host: useRuntimeConfig().public.posthogHost,
7+
// recommended: keep pageview manual so you can gate it
8+
capture_pageview: false,
9+
// If you use PostHog cookieless mode, you can set it here (see PostHog docs/tutorial)
10+
// cookieless: 'on_reject',
11+
}) // :contentReference[oaicite:2]{index=2}
12+
13+
const enable = () => {
14+
posthog.opt_in_capturing()
15+
posthog.capture('$pageview')
2716
}
28-
}
29-
30-
export default defineNuxtPlugin(() => {
31-
const runtimeConfig = useRuntimeConfig()
32-
33-
// IMPORTANT: set this to the cookie name you configured in nuxt-cookie-consent
34-
const CONSENT_COOKIE_NAME = 'cookie_consent' // <-- adjust if your config uses a different name
35-
const consentRaw = useCookie<string | undefined>(CONSENT_COOKIE_NAME)
36-
37-
let inited = false
3817

39-
const init = () => {
40-
if (inited) return
41-
inited = true
18+
const disable = () => {
19+
posthog.opt_out_capturing()
20+
}
4221

43-
posthog.init(runtimeConfig.public.posthogPublicKey, {
44-
api_host: runtimeConfig.public.posthogHost,
45-
defaults: runtimeConfig.public.posthogDefaults,
22+
const applyFromCookieScript = () => {
23+
// Wait for CookieScriptLoaded before using instance functions
24+
// currentState() gives { action: 'accept'|'reject', categories: [...] }
25+
// :contentReference[oaicite:3]{index=3}
26+
// @ts-expect-error CookieScript is global
27+
const state = window.CookieScript?.instance?.currentState?.()
28+
if (!state) return
4629

47-
person_profiles: 'identified_only',
48-
capture_pageview: false, // avoid firing before you decide
49-
respect_dnt: true,
50-
disable_session_recording: true,
30+
// Pick the category you map analytics to (commonly "performance")
31+
const analyticsAllowed =
32+
state.action === 'accept' && Array.isArray(state.categories) && state.categories.includes('performance')
5133

52-
loaded: (ph) => {
53-
if (import.meta.env.MODE === 'development') ph.debug()
54-
ph.capture('$pageview')
55-
}
56-
})
34+
if (analyticsAllowed) enable()
35+
else disable()
5736
}
5837

59-
const shutdown = () => {
60-
// user withdrew consent
61-
posthog.opt_out_capturing()
62-
posthog.reset()
63-
inited = false
64-
}
38+
// 2) Update PostHog when CookieScript is ready + whenever consent changes
39+
window.addEventListener('CookieScriptLoaded', applyFromCookieScript) // :contentReference[oaicite:4]{index=4}
40+
window.addEventListener('CookieScriptAcceptAll', enable) // :contentReference[oaicite:5]{index=5}
41+
window.addEventListener('CookieScriptReject', disable) // :contentReference[oaicite:6]{index=6}
42+
window.addEventListener('CookieScriptAccept', applyFromCookieScript) // e.detail.categories exists :contentReference[oaicite:7]{index=7}
6543

66-
// init if already consented
67-
if (hasAnalyticsConsent(consentRaw.value)) init()
44+
// Optional: if you only care about analytics category, this fires once per page when allowed:
45+
window.addEventListener('CookieScriptCategory-performance', enable) // :contentReference[oaicite:8]{index=8}
6846

69-
// react to consent changes
70-
watch(
71-
() => consentRaw.value,
72-
(val, oldVal) => {
73-
const now = hasAnalyticsConsent(val)
74-
const before = hasAnalyticsConsent(oldVal)
75-
76-
if (now && !before) init()
77-
if (!now && before) shutdown()
78-
}
79-
)
80-
81-
return {
82-
provide: {
83-
posthog
84-
}
85-
}
47+
// 3) Gate SPA pageviews
48+
nuxtApp.$router.afterEach(() => {
49+
if (posthog.has_opted_in_capturing?.()) posthog.capture('$pageview')
50+
}) // :contentReference[oaicite:9]{index=9}
8651
})

0 commit comments

Comments
 (0)