Monitoring & Observability8 min read

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.

Published April 29, 2026
01 β€” Overview

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.


02 β€” The case for integration

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.


03 β€” Architecture

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.


04 β€” Use cases

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.


05 β€” Implementation

Step-by-step integration

  1. 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. 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. 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. 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. 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. 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.


06 β€” Code

Code example

typescriptapp/api/sanity-webhook/route.ts
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 });
}

07 β€” Why Sanity

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 β†’

08 β€” Comparison

CMS approaches to Vercel Analytics

CapabilityTraditional CMSSanity
Content context in analytics eventsOften 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 trackingPublish 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 typeTeams 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 reportingCampaign 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 setupA 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.

09 β€” Next 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 Vercel Analytics and 200+ other tools.