From 448b5a043e531b5ce652cdce2099dca981a6de57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Wed, 27 May 2026 14:31:52 +0200 Subject: [PATCH] Gate manual PostHog ping when opted out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PostHog's `cookieless_mode` keeps `is_capturing()` returning `true` after rejection: in `"always"` mode `opt_out_capturing()` is a no-op that just warns, and in `"on_reject"` mode it actually registers a cookieless distinct_id and re-fires a pageview rather than stopping captures. The example panel's "Capture test event" button therefore still shipped events (cookielessly) for visitors who had rejected consent, contradicting the "only delivered when opted in" hint. Disable the button whenever the cached status reports opted out, and keep a defensive `has_opted_out_capturing()` check in the click handler so the example fails closed if the panel is reused without its disabled-state wiring. Drop the now-redundant disclaimer next to the last-sent timestamp. Signed-off-by: Émile Ré --- .../cookie-banner-react/src/tabs/ThemedBannerTab.tsx | 9 +++++++++ .../src/tabs/_components/PosthogPanel.tsx | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/examples/cookie-banner-react/src/tabs/ThemedBannerTab.tsx b/examples/cookie-banner-react/src/tabs/ThemedBannerTab.tsx index c90e367c6..7b526e67c 100644 --- a/examples/cookie-banner-react/src/tabs/ThemedBannerTab.tsx +++ b/examples/cookie-banner-react/src/tabs/ThemedBannerTab.tsx @@ -55,6 +55,15 @@ export function ThemedBannerTab({ events, pushEvent }: ThemedBannerTabProps) { ); const sendPing = useCallback(() => { + // Defensive: `PosthogPanel` already disables the button while opted out, + // and pure telemetry pings like this one are fine to ship cookielessly + // (PostHog's `cookieless_mode` is designed exactly for that). Only gate + // manual captures when the event carries user-specific data — e.g. an + // identified `distinct_id`, an email, a workspace name — that must not + // leave the browser without consent. We keep the guard here purely to + // make the example fail closed if the panel is reused without its + // disabled-state wiring. + if (posthog.has_opted_out_capturing()) return; posthog.capture("themed_tab_manual_ping", { source: "example" }); setManualPing(new Date().toISOString()); }, []); diff --git a/examples/cookie-banner-react/src/tabs/_components/PosthogPanel.tsx b/examples/cookie-banner-react/src/tabs/_components/PosthogPanel.tsx index 8e09bfe31..8addcb288 100644 --- a/examples/cookie-banner-react/src/tabs/_components/PosthogPanel.tsx +++ b/examples/cookie-banner-react/src/tabs/_components/PosthogPanel.tsx @@ -58,14 +58,14 @@ export function PosthogPanel({ status, manualPing, onSendPing }: PosthogPanelPro {manualPing && ( - last sent: {manualPing} (only delivered when opted in) + last sent: {manualPing} )}