How to Integrate PostHog with Your Headless CMS
Connect PostHog to your content layer so product, growth, and editorial teams can see which pages, authors, campaigns, and content variants lead to signups, activation, and retention.
What is PostHog?
PostHog is an open-source product analytics platform for event tracking, session replay, feature flags, experiments, surveys, and product data workflows. Product, engineering, growth, and data teams use it to understand what users do inside websites and apps, then test changes based on real behavior. It competes with tools like Amplitude, Mixpanel, Heap, and feature-flag platforms, while also offering self-hosting for teams that need more control over their analytics stack.
Why integrate PostHog with a headless CMS?
PostHog tells you what users did. Your content layer tells you what they saw. When those systems aren't connected, you're stuck with analytics like page_path = /blog/launch-post and event = signup_clicked, but you can't reliably answer which Sanity document, author, topic, locale, CTA variant, or campaign field produced that behavior.
Architecture overview
A typical Sanity and PostHog integration has two flows. First, content editors publish a document in Sanity Studio. That document is written to the Content Lake, and a GROQ-powered webhook or Sanity Function runs only for the document types you care about, such as article, landingPage, docsPage, or campaign. The handler receives the mutation event, fetches the published document from the Content Lake with GROQ, joins references like author or category, and sends a server-side event to PostHog using the PostHog Node SDK or Capture API. For example, it can capture content_published with properties such as content_id, slug, content_type, locale, author, campaign, and experiment_id.
Common use cases
Content performance by source document
Attach Sanity document IDs, slugs, authors, topics, and locales to PostHog events so teams can compare signup, activation, and retention by content record instead of URL alone.
Experiment reporting for content variants
Model headline, CTA, or page variants in Sanity, serve the selected variant in your app, and capture experiment_id and variant in PostHog for conversion analysis.
Feature flag controlled content
Use PostHog feature flags to decide which Sanity content variant to show, then record which version each user saw and what they did next.
Session replay with content context
Send content_id, slug, locale, and campaign fields to PostHog so teams can filter replays to sessions that viewed a specific article, docs page, or launch campaign.
Step-by-step integration
- 1
Set up PostHog
Create a PostHog project, choose your host region or self-hosted URL, and copy the project API key from Project settings. Install posthog-js for frontend events and posthog-node for server-side capture events.
- 2
Model analytics fields in Sanity Studio
Add fields that analytics teams can trust, such as analyticsKey, campaignId, experimentId, canonicalPath, locale, and contentType. If the content has authors, topics, or products, model them as references so GROQ can join them into PostHog event properties.
- 3
Create a publish trigger
Use a Sanity webhook with a GROQ filter such as _type in ['article', 'landingPage', 'docsPage'] and !(_id in path('drafts.**')). For server-side logic inside Sanity, use Functions to react to content mutations without running separate infrastructure.
- 4
Fetch the exact content fields with GROQ
In the webhook handler or Function, use @sanity/client to fetch the published document by ID. Project only the fields PostHog needs, including joined references like author->name and category->slug.current.
- 5
Send events to PostHog
Use the PostHog Node SDK or Capture API to capture events such as content_published, content_updated, and content_unpublished. Use consistent property names, because PostHog breakdowns and funnels depend on clean event data.
- 6
Test frontend tracking
Initialize posthog-js in your app, query Sanity for the page, and include Sanity metadata on $pageview and CTA events. Confirm the events in PostHog Live Events, then build dashboards for content conversion, funnel drop-off, and experiment results.
How Sanity + PostHog works
Build your PostHog integration on Sanity
Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect PostHog data with the content your users actually experience.
Start building free โCMS approaches to PostHog
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Content metadata for analytics events | Schema fields like analyticsKey, campaignId, experimentId, and locale live with the content and can be sent to PostHog as typed JSON. | |
| Publish-time sync to PostHog | GROQ-powered webhooks can trigger only for the published documents you choose, and Functions can run the server-side PostHog call. | |
| Field-level control over event payloads | GROQ can select exact fields, join references, and shape the payload before sending it to PostHog. | |
| A/B test content support | Developers can model variants in schema-as-code, editors can work in Sanity Studio, and apps can send experiment_id and variant to PostHog. | |
| Setup trade-offs | Requires clear schema design and event naming decisions, but gives you precise control over the content data PostHog receives. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Google Analytics
Connect Sanity content metadata to GA4 events for traffic, acquisition, and conversion reporting across pages and campaigns.
Sanity + Segment
Send Sanity-backed content properties into Segment so multiple analytics destinations receive the same clean event context.
Sanity + Amplitude
Analyze product funnels and retention using Sanity document IDs, content types, campaigns, and experiment fields as event properties.