How to Integrate FullStory with Your Headless CMS
Connect FullStory to structured content so product, UX, and marketing teams can replay sessions, analyze behavior, and tie every click back to the exact content users saw.
What is FullStory?
FullStory is a digital experience intelligence platform that records user sessions, captures product analytics events, and helps teams investigate friction such as rage clicks, dead clicks, JavaScript errors, and drop-offs. Product, UX, support, engineering, and growth teams use it to understand what happened in a session without relying only on aggregate dashboards.
Why integrate FullStory with a headless CMS?
FullStory shows you what users did. Your headless CMS category system tells you what they were looking at. When those two systems are disconnected, teams end up comparing URLs, campaign spreadsheets, release notes, and analytics exports by hand. That works for one landing page. It breaks when you have 800 product pages, 12 locales, rotating campaigns, and weekly content releases.
Connecting FullStory to structured content gives every captured session more context. Instead of only searching for sessions on `/products/running-shoe`, you can filter or analyze behavior by content type, product category, locale, authoring team, campaign ID, release ID, or experiment variant. That makes questions much easier to answer, like, "Did users rage-click more on the Spanish pricing page after Friday's copy update?" or "Which sessions saw the new comparison table before conversion dropped?"
A structured back end matters here. With Sanity's AI Content Operating System, content in the Content Lake is typed JSON, so you don't need to scrape HTML or parse page blobs to send useful metadata to FullStory. GROQ selects exactly the fields FullStory needs, webhooks trigger when content is published, updated, or deleted, and Functions can run sync logic server-side without a separate queue or worker. The trade-off is that you'll still need to decide which content fields belong in FullStory. Sending every field can create noisy analytics and expose data you don't want in a behavior tool.
Architecture overview
A typical Sanity and FullStory integration has two paths: a content event path and a user-session path. On the content side, editors publish or update a document in Sanity Studio. The mutation lands in the Content Lake, then a Sanity webhook fires on the publish event. A Sanity Function, webhook listener, or small middleware endpoint receives the document ID, runs a GROQ query to fetch the fields FullStory needs, and calls FullStory's Events API to record a content lifecycle event such as `Sanity Content Published`. On the user-session side, your frontend loads FullStory through its browser SDK, usually `@fullstory/browser` or the FullStory snippet. When a user views a page, your app passes content metadata from Sanity to FullStory as custom event properties or user/session variables, such as `contentId`, `contentType`, `slug`, `locale`, `campaignId`, and `experimentVariant`. FullStory then records the session replay, clicks, errors, page views, and custom events with that content context attached. The end user doesn't see the integration. They just visit the site or app. Behind the scenes, Sanity provides the structured content, GROQ controls the payload, webhooks or Functions handle publish-time events, and FullStory captures the behavioral record that product and UX teams can search later.
Common use cases
Find sessions by content metadata
Search FullStory sessions by Sanity fields like content type, campaign ID, locale, product category, or experiment variant instead of relying only on URLs.
Debug conversion drops after publishing
Send content publish events to FullStory so teams can compare session behavior before and after a pricing page, onboarding flow, or product detail page changed.
Investigate rage clicks on specific content
Filter FullStory rage-click and dead-click sessions to a specific Sanity document, such as a help article, landing page, or product comparison block.
Analyze content experiments
Pass Sanity-controlled variant IDs into FullStory events so UX and growth teams can replay sessions for each copy, layout, or CTA version.
Step-by-step integration
- 1
Set up FullStory
Create a FullStory account, get your Org ID from FullStory settings, and install the browser SDK with `npm install @fullstory/browser`. Initialize it in your app with `init({ orgId: 'YOUR_ORG_ID' })`, then confirm sessions appear in FullStory. If you're sending server-side content events, create an API key in FullStory settings and keep it in server-only environment variables.
- 2
Model analytics-ready content in Sanity Studio
Add fields that help explain user behavior, not just fields that render the page. For a landing page, that might include `title`, `slug`, `locale`, `campaignId`, `audience`, `experimentVariant`, `primaryCta`, and references to related products or categories.
- 3
Query only the fields FullStory needs
Write a GROQ query that fetches the document ID, type, slug, locale, campaign fields, and referenced category or product names. Keep private editorial notes, drafts, approval comments, and internal planning fields out of the FullStory payload.
- 4
Create the sync mechanism
Use a Sanity webhook filtered to publish mutations, or use a Sanity Function if you want the logic to run inside Sanity's event system. The handler receives the changed document ID, fetches the current published document from the Content Lake, and sends a `Sanity Content Published` event to FullStory's Events API.
- 5
Add FullStory tracking to the frontend
In your website or app, initialize FullStory and send a page event when Sanity content renders. Include fields such as `contentId`, `contentType`, `slug`, `locale`, and `campaignId`, so FullStory sessions can be filtered by the content users actually saw.
- 6
Test with one document and one session
Publish a test page in Sanity Studio, check that your webhook or Function sends the FullStory event, visit the page in a test browser, and confirm the session includes the expected content metadata. Then test an update, an unpublished page, and a locale variant before rolling it out to every content type.
How Sanity + FullStory works
Build your FullStory integration on Sanity
Sanity gives you the structured content foundation, real-time event system, and flexible APIs you need to connect content changes and user behavior in FullStory.
Start building free โCMS approaches to FullStory
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Content metadata for session replay | Often tied to rendered pages, templates, or plugins, so analytics teams may rely on URL patterns and manual naming rules. | Content is structured in the Content Lake as typed JSON, making fields like campaign, locale, variant, and category ready for FullStory events. |
| Publish-time event tracking | Usually handled with plugins, scheduled exports, or custom server code that may not fire consistently across content types. | Webhooks and Functions can trigger on mutations, fetch the final published document, and send the right event payload to FullStory. |
| Field-level control | Teams often send page-level data because field-level content can be hard to access outside the rendering layer. | GROQ can fetch, filter, project, and join referenced content in one query, so FullStory receives a focused payload. |
| Experiment and campaign context | Campaign metadata may live in spreadsheets, tag managers, or page naming conventions. | Campaign IDs, audience fields, release data, and variant references can live in the schema and travel with the content to FullStory. |
| Frontend tracking setup | Usually depends on template access, plugin compatibility, and whether developers can add custom FullStory calls where content renders. | Frontend apps can query Sanity content and pass the same document metadata into FullStory browser events on page view. |
| Operational trade-offs | Lower initial setup if a plugin exists, but less control over data shape and event quality. | More planning up front for schema design and field governance, but cleaner analytics data once the integration is running. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Google Analytics
Track traffic, conversions, and content engagement across Sanity-powered pages with GA4 events and content metadata.
Sanity + Segment
Use Segment to route Sanity content events and frontend behavior data to FullStory, warehouses, and product analytics tools.
Sanity + Amplitude
Connect Sanity content fields to Amplitude funnels, cohorts, and retention analysis for product-led content experiences.