PostHog analytics and feature flags setup
Quick Guide: One-time setup for PostHog analytics and feature flags. Covers
posthog-jsclient provider,posthog-nodeserver client, and environment variables. PostHog handles both analytics AND feature flags with a generous free tier (1M events + 1M flag requests/month).
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST initialize posthog-js only in a client/browser context - it requires browser APIs like window and localStorage)
(You MUST call , , or use after server-side event capture to prevent lost events)
<philosophy> </philosophy> <patterns> </patterns>posthog.shutdown()posthog.flush()captureImmediate()(You MUST use defaults: '2026-01-30' for automatic SPA page tracking and latest recommended behaviors)
</critical_requirements>
Auto-detection: PostHog setup, posthog-js, posthog-node, PostHogProvider, analytics setup, feature flags setup, event tracking setup, posthog.init
When to use:
When NOT to use:
Key patterns covered:
Detailed Resources:
PostHog is a product analytics + feature flags platform that consolidates multiple tools into one. It's open-source, can be self-hosted, and has a generous free tier. For solo developers and small teams, PostHog eliminates the need for separate analytics and feature flag services.
Core principles:
When to use PostHog:
When NOT to use PostHog:
Use a single PostHog organization for your apps. One org pools billing. Use separate projects per app, or one project with custom properties to filter.
PostHog Organization: "Your Company"
├── Project: "Main App" (or separate per app)
│ ├── API Key: phc_xxx
│ └── Host: https://us.i.posthog.com (or eu.i.posthog.com)
Why good: Single org pools billing across all projects, usage-based pricing, 6 projects included on paid tier
Install posthog-js and configure a provider or use your framework's client-side initialization hook.
Key config options: defaults: "2026-01-30" enables recommended behaviors, person_profiles: "identified_only" reduces costs.
See examples/core.md for full implementation of both approaches.
Why good: defaults date enables automatic SPA page/leave tracking, person_profiles: "identified_only" reduces event costs, debug mode in development aids troubleshooting
Install posthog-node and create a singleton for server-side event capture.
Serverless flush options:
captureImmediate() - simplest, awaits HTTP request directly (one request per event)capture() + await flush() - batched, requires explicit flush before response returnsSee examples/server.md for singleton setup, API route usage, and the flush anti-pattern.
Why good: Singleton prevents multiple client instances, flushInterval/flushAt configure batching, captureImmediate simplifies serverless usage
<red_flags>
flush() or captureImmediate() after server-side capture in serverless environments (events silently lost)posthog.reset() on sign out (user identity bleeds to next session)defaults date option (manual pageview tracking required, misses recommended behaviors)posthog.identify() after authentication (anonymous and authenticated sessions remain unlinked)person_profiles: 'identified_only' option (unnecessary anonymous profiles created, higher costs)Gotchas & Edge Cases:
posthog-js must be initialized after window is available (hence useEffect or a client-side initialization hook)flush(), shutdown(), or use captureImmediate()captureImmediate() is simpler for serverless but sends one HTTP request per event (no batching)person_profiles: 'identified_only' reduces costs but means no anonymous user profiles are created</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST initialize posthog-js only in a client/browser context - it requires browser APIs like window and localStorage)
(You MUST call posthog.shutdown(), posthog.flush(), or use captureImmediate() after server-side event capture to prevent lost events)
(You MUST use defaults: '2026-01-30' for automatic SPA page tracking and latest recommended behaviors)
Failure to follow these rules will cause lost analytics events, broken tracking, or security vulnerabilities.
</critical_reminders>