fix(analytics): fall back to server-evaluated feature flags when posthog-js is blocked#3131
Merged
Merged
Conversation
…hog-js is blocked The Timeline tab (is-timeline-enabled) is gated by useFeatureFlag, which relied solely on the browser's posthog-js /flags request. Ad blockers, privacy browsers, and corporate proxies block that request (the /ingest proxy path is on public blocklists), so the flag never resolved and the tab never rendered for affected customers — while impersonating staff on unblocked machines saw it fine. The org layout already evaluates all flags server-side (posthog-node with the organization group) for nav gating. Provide that map to the client via a new ServerFeatureFlagsProvider and let useFeatureFlag treat the flag as enabled when either the live client value or the server-evaluated value says so. No changes needed at the flag call sites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
🎉 This PR is included in version 3.82.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Customer report: the
is-timeline-enabledPostHog flag was toggled on fororg_69cc72ba1ff5244c2f492f7b, but the customer never saw the Timeline tab on the Overview page — while impersonating staff saw it fine. Cache clears, cookies, hard reset, and incognito all failed.Root cause
The Timeline tab is the only flag-gated UI that depends on the client-side posthog-js flags request (
/ingest/flags). When that request is blocked — ad blocker, privacy browser, AdGuard, corporate proxy (all survive incognito and cache clears) —useFeatureFlagEnabledstaysundefinedforever, souseFeatureFlagreturnsfalseand the tab never renders. PostHog documents that the flags endpoint is routinely blocked and that generic proxy paths like/ingestare on public blocklists.Impersonation proves the server-side flag state is correct: better-auth impersonation uses the customer's own user ID and the same org group, so the flag inputs are identical — the only difference is the staff member's unblocked browser.
The org layout already evaluates three other nav flags server-side via posthog-node (blocker-immune); the timeline flag was the odd one out.
Fix
packages/analytics: newServerFeatureFlagsProvidercontext +useFeatureFlagnow treats a flag as enabled when either the live posthog-js value or the server-evaluated value says so. The OR matters: a blocked client can also serve a stalefalsepersisted from an old session, and only the fresher server value can override it.apps/app[orgId]/layout.tsx: the flag map the layout already fetches server-side (getFeatureFlags(userId, { groups: { organization } })) is now passed into the provider.OverviewTabs,FrameworkDetailContent,FrameworkTimeline), and any futureuseFeatureFlagusage under the org layout is covered automatically.Behavior notes:
Testing
OverviewTabs.test.tsx: hook fallback semantics (no provider / server-true / multivariate string / both-false / stale-live-false-vs-server-true / live-only) + tab rendering through the real component in the blocked-client scenario.@trycompai/analyticstypecheck green; app typecheck has zero errors in touched files (remaining failures reproduce identically on main without this change).🤖 Generated with Claude Code
Summary by cubic
Fallback to server-evaluated PostHog flags when the browser blocks
posthog-js, so Timeline and other flag-gated UI render correctly. Handles ad blockers and proxies that previously hid Timeline even when enabled.ServerFeatureFlagsProviderin@trycompai/analytics;useFeatureFlagnow enables a flag when the liveposthog-jsvalue OR the server-evaluated value is on (true or a non-empty variant).[orgId]/layout.tsxevaluates flags withposthog-node, derives existing nav booleans, and wraps the app shell withServerFeatureFlagsProviderto pass the full map; existing consumers need no changes.Written for commit 022f2b9. Summary will update on new commits.