Personalization & Experimentation8 min read

How to Integrate Statsig with Your Headless CMS

Connect Statsig to your headless CMS so experiments, feature gates, and personalized content use the same structured copy your editors publish.

Published April 29, 2026
01Overview

What is Statsig?

Statsig is a feature flagging, experimentation, and product analytics platform for product and engineering teams. It evaluates Feature Gates, Dynamic Configs, Experiments, Layers, and Autotune settings per user or account through server, client, and mobile SDKs. Teams use Statsig to control rollouts, run A/B tests, and measure exposure and event data in one workflow.


02The case for integration

Why integrate Statsig with a headless CMS?

Personalization gets messy when experiment logic and content live in separate places. A growth team might define a Statsig experiment with variants A, B, and C, while editors update landing page headlines, CTAs, and hero images somewhere else. If someone copies the wrong CTA into a Dynamic Config, the experiment still runs, but the result is noisy because the content doesn’t match the test plan.

Connecting Statsig to a headless CMS solves that handoff. Editors publish structured variants, developers sync only the fields Statsig needs, and Statsig handles assignment, bucketing, and measurement. With Sanity, content in the Content Lake is typed JSON, so a GROQ query can pull a config name, variant keys, headlines, CTA labels, image URLs, and audience metadata without scraping HTML or parsing page blobs.

The alternative is usually manual and brittle. Someone exports copy into a spreadsheet, pastes it into Statsig, waits for a deploy, or asks an engineer to update a config file. Webhooks and Functions remove that lag. When content is published, the sync can run immediately, call the Statsig Console API, and keep the frontend experience tied to the exact content editors approved.


03Architecture

Architecture overview

A typical Sanity and Statsig integration starts with an experiment document in Sanity Studio. The schema includes fields like statsigConfigName, experimentKey, variants, audience notes, CTA copy, and references to shared content such as products, plans, or articles. When that document is published, a Sanity webhook fires with the document ID and mutation details. A webhook handler or Sanity Function receives the event, verifies the request, and uses @sanity/client to fetch the published document from the Content Lake. GROQ selects only the fields Statsig needs, including joined reference data such as image asset URLs or product slugs. The server-side handler then calls the Statsig Console API, for example PATCH https://statsigapi.net/console/v1/dynamic_configs/{configName}, using a Console API key stored as a server-side secret. The payload can update a Dynamic Config default value or experiment metadata with Sanity-authored variants. On the frontend, your app initializes the Statsig SDK, evaluates the experiment or Dynamic Config for the current user, and renders the matching Sanity content. Statsig handles allocation and exposure logging. Sanity remains the source for the content itself. There’s one important trade-off. Don’t sync drafts, personal data, or large content payloads into Statsig. Keep Statsig payloads small, usually variant keys, labels, IDs, and URLs, then fetch full content from Sanity when needed.


04Use cases

Common use cases

🧪

A/B test homepage messaging

Publish headline and CTA variants in Sanity, sync them to a Statsig Dynamic Config, and let Statsig assign users to each variant.

🚦

Gate content launches

Use Statsig Feature Gates to show a new pricing page, campaign module, or onboarding step only to beta accounts or a percentage rollout.

🎯

Personalize by account or audience

Send audience-safe variant keys from Sanity to Statsig, then render different content for free users, enterprise accounts, or trial users.

📊

Measure content variant results

Connect Statsig exposure and event data to specific Sanity variant IDs so teams know which headline, CTA, or layout won.


05Implementation

Step-by-step integration

  1. 1

    Set up Statsig keys and SDKs

    Create or open a Statsig project, copy a Server Secret Key for SDK evaluation, copy a Console API key for config updates, and install the SDK you need, such as statsig-node on the server or @statsig/js-client in the browser.

  2. 2

    Model experiment content in Sanity Studio

    Create a schema for experiment content with fields such as statsigConfigName, experimentKey, variants, key, headline, ctaLabel, image, and targetPage. Keep variant keys stable, such as control, short_headline, and benefit_led.

  3. 3

    Create a publish webhook

    In Sanity, add a webhook that triggers on publish events for your experiment document type. Send the document ID and type to your webhook handler, Sanity Function, or middleware endpoint.

  4. 4

    Fetch the published content with GROQ

    In the handler, use @sanity/client with useCdn set to false so you read the latest published data. Use GROQ to select only fields Statsig should receive, such as variant keys, CTA labels, and image URLs.

  5. 5

    Update Statsig through the Console API

    Call the Statsig Console API with your Console API key and update the matching Dynamic Config or experiment metadata. Keep secrets server-side, and avoid sending draft content or user data.

  6. 6

    Test assignment and rendering

    Initialize the Statsig SDK in your app, evaluate the Dynamic Config or experiment for a test user, confirm exposure events appear in Statsig, and verify the rendered content matches the Sanity variant.


06Code

Code example

typescriptapp/api/sanity-statsig/route.ts
import {createClient} from '@sanity/client'
import {NextRequest, NextResponse} from 'next/server'

const sanity = createClient({
  projectId: process.env.SANITY_PROJECT_ID!,
  dataset: process.env.SANITY_DATASET!,
  apiVersion: '2025-02-19',
  token: process.env.SANITY_READ_TOKEN!,
  useCdn: false,
})

export async function POST(req: NextRequest) {
  if (req.headers.get('x-webhook-secret') !== process.env.SANITY_WEBHOOK_SECRET) {
    return NextResponse.json({error: 'Unauthorized'}, {status: 401})
  }

  const {_id} = await req.json()
  const id = _id.replace(/^drafts\./, '')

  const experiment = await sanity.fetch(`*[_id == $id][0]{
    "configName": statsigConfigName,
    "variants": variants[]{key, headline, ctaLabel, "imageUrl": image.asset->url}
  }`, {id})

  if (!experiment?.configName) {
    return NextResponse.json({ok: true, skipped: true})
  }

  const statsigRes = await fetch(
    `https://statsigapi.net/console/v1/dynamic_configs/${encodeURIComponent(experiment.configName)}`,
    {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        'STATSIG-API-KEY': process.env.STATSIG_CONSOLE_API_KEY!,
      },
      body: JSON.stringify({defaultValue: {variants: experiment.variants}}),
    }
  )

  if (!statsigRes.ok) {
    throw new Error(`Statsig update failed: ${await statsigRes.text()}`)
  }

  return NextResponse.json({ok: true})
}

07Why Sanity

How Sanity + Statsig works

Build your Statsig integration on Sanity

Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect published content with Statsig experiments and feature gates.

Start building free →

08Comparison

CMS approaches to Statsig

CapabilityTraditional CMSSanity
Experiment content structureOften stores test copy inside pages, which makes variant reuse across apps hard.Schema-as-code models experiments, variants, references, and approval fields as typed content.
Sync timing after publishUsually needs manual copy-paste, scheduled exports, or deploy steps.Webhooks and Functions can trigger Statsig updates on publish without a separate worker service.
Payload control for StatsigPage HTML or large content blobs can include fields Statsig doesn’t need.GROQ returns only the config name, variant keys, labels, URLs, and IDs required for the Statsig call.
Editor workflow for test variantsEditors may need developer help to create new experiment variants safely.Sanity Studio can give editors custom fields, validation, previews, Comments, Tasks, and Content Releases for planned tests.
Multi-channel personalizationExperiments are often tied to one website template.The same structured variant content can feed web, mobile, Statsig configs, and AI agents from the Content Lake.

09Next steps

Keep building

Explore related integrations to complete your content stack.

Ready to try Sanity?

See how Sanity's Content Operating System powers integrations with Statsig and 200+ other tools.