How to Integrate Vercel Analytics with Your Headless CMS
Connect Vercel Analytics to structured content so you can see which pages, authors, topics, and releases affect traffic, Core Web Vitals, and custom content events.
What is Vercel Analytics?
Vercel Analytics is a first-party analytics product for sites and apps deployed on Vercel. It tracks pageviews, visitors, referrers, Core Web Vitals, and custom events without adding a third-party analytics script. Teams using Next.js, React, SvelteKit, Astro, and other Vercel-supported frameworks often use it as their native view into frontend performance and content engagement.
Why integrate Vercel Analytics with a headless CMS?
When analytics only knows about URLs, your team has to translate performance data by hand. A report might show that `/blog/ai-buying-guide` had a 3.1-second LCP on mobile and 14,000 visits, but it wonβt tell you the author, topic, content type, campaign, locale, or release that produced that result unless you send that context with the event.
Architecture overview
A typical setup has two event paths. First, the frontend renders content from Sanityβs Content Lake and includes the Vercel Analytics SDK, such as `@vercel/analytics/next`, so pageviews and Web Vitals are captured when a visitor loads the page. Second, Sanity sends a webhook when a document is published, updated, or deleted. The webhook calls a Vercel Route Handler, or a Sanity Function can run on the same mutation and call that endpoint. The handler uses `@sanity/client` and GROQ to fetch only the fields Vercel Analytics needs, for example `_id`, `_type`, `slug.current`, `author->name`, `category->title`, and `release`. It then calls Vercel Analytics through the server SDK, usually `track` from `@vercel/analytics/server`, to record a custom event like `content_published`. The end user still gets the normal website experience, while your analytics dashboard gets content-aware events that connect performance and engagement back to the source document.
Common use cases
Content performance by topic
Send `topic`, `author`, and `contentType` with custom events so teams can compare traffic and engagement across editorial categories.
Core Web Vitals by template
Attach Sanity document types to page views so you can spot whether product pages, landing pages, or articles are causing LCP or CLS regressions.
Publish event tracking
Record a Vercel Analytics event the moment a page goes live, then compare publish time against the first visits, referrers, and conversion events.
Campaign and test metadata
Model campaign IDs, variants, and audience fields in Sanity, then pass them to Vercel Analytics custom events for cleaner reporting.
Step-by-step integration
- 1
Enable Vercel Analytics
In Vercel, open your project, go to Analytics, and enable Web Analytics. For a Next.js app, install the SDK with `npm i @vercel/analytics`, then add `import { Analytics } from '@vercel/analytics/next'` and render `<Analytics />` in your root layout. Standard Vercel Analytics event collection doesnβt require an API key. If you also use the Vercel REST API for reporting automation, create a Vercel token and store it as `VERCEL_TOKEN`.
- 2
Model analytics-ready content in Sanity Studio
Add fields that youβll want to see in analytics reports, such as `slug`, `title`, `author`, `category`, `locale`, `campaignId`, and `experimentVariant`. Keep these fields structured instead of hiding them in rich text, because event properties need predictable values.
- 3
Create a Sanity webhook for publish events
In Sanity, create a webhook that fires on create, update, and delete for published documents. Use a GROQ filter such as `*[_type in ['post','page','product'] && !(_id in path('drafts.**'))]`, and send a small projection like `{_id, _type}` to your Vercel endpoint.
- 4
Fetch content context with GROQ
In the Vercel Route Handler, use `@sanity/client` to fetch the document that triggered the webhook. Query only the fields you need for analytics properties, including joined references like `author->name` and `category->title`.
- 5
Track the content event in Vercel Analytics
Call `track` from `@vercel/analytics/server` inside your Vercel endpoint. Use clear event names like `content_published`, `content_updated`, or `content_deleted`, and keep property values short enough for analytics reporting.
- 6
Test the frontend and the webhook path
Deploy to Vercel, publish a test document in Sanity Studio, and confirm two things: the page records views through the Vercel Analytics component, and the webhook creates a custom event with the Sanity document ID, slug, type, and topic.
Code example
import { NextRequest, NextResponse } from 'next/server';
import { track } from '@vercel/analytics/server';
import { createClient } from '@sanity/client';
const sanity = createClient({
projectId: process.env.SANITY_PROJECT_ID!,
dataset: process.env.SANITY_DATASET!,
apiVersion: '2025-01-01',
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 body = await req.json();
const id = String(body._id || '').replace(/^drafts\./, '');
const doc = await sanity.fetch(
`*[_id == $id][0]{
_id,
_type,
title,
"slug": slug.current,
"author": author->name,
"topic": category->title
}`,
{ id }
);
if (!doc) return NextResponse.json({ ok: true, skipped: true });
await track('content_published', {
id: doc._id,
type: doc._type,
slug: doc.slug || '',
author: doc.author || '',
topic: doc.topic || '',
});
return NextResponse.json({ ok: true });
}How Sanity + Vercel Analytics works
Build your Vercel Analytics integration on Sanity
Sanity gives you the structured content foundation, real-time event system, and flexible APIs to connect Vercel Analytics to the content signals your team actually uses.
Start building free βCMS approaches to Vercel Analytics
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Content context in analytics events | Often tied to page templates or plugins, so analytics usually sees URLs before it sees structured fields. | GROQ can return document ID, slug, author, topic, locale, and campaign data in one query for Vercel Analytics properties. |
| Publish and update tracking | Publish events may require a plugin, custom theme code, or a scheduled export. | GROQ-filtered webhooks and Functions can trigger only for the document types and states you care about. |
| Core Web Vitals by content type | Teams often map URLs to templates after the fact in spreadsheets or BI tools. | The frontend can fetch page metadata from the Content Lake and send content type, locale, and release data alongside Vercel Analytics events. |
| Campaign and experiment reporting | Campaign fields are commonly embedded in page copy or plugin settings, which makes reporting inconsistent. | Schema-as-code lets you define required campaign IDs, variants, and audience fields, then reuse them in analytics events. |
| Operational setup | A plugin may work quickly, but custom analytics behavior can become hard to version and test. | Use a webhook to a Vercel Route Handler, or run a Sanity Function on mutation, then fetch exactly what Vercel Analytics needs. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Sentry
Connect content releases to frontend errors so teams can see whether a publish introduced a regression.
Sanity + Datadog
Send content change events into Datadog to correlate publishes with latency, traffic, and infrastructure metrics.
Sanity + LogRocket
Pair session replay with Sanity document metadata to watch how users interact with specific pages and content variants.