The official Clean Next.js + Sanity template powered by Sanity for content management
and Croct for real-time personalization and AB testing.
Clean Next.js + Sanity is Sanity's official starter: a Sanity Studio with predefined content types and sample data, plus a Next.js App Router client with real-time visual editing.
This project is a fork of that template that adds Croct on top to enable real-time personalization and A/B testing by using dynamic content. It's the fastest way to add AB testing and personalization on top of Sanity Studio.
Croct is a headless platform for conversion optimization that pairs nicely with Sanity. Using Croct, you get:
- Server-side AB testing support with real-time audience segmentation
- Server-side content personalization based on location, behavior, or custom rules
- Visitor profile explorer so you can dive deeper and analyze the user journey using out-of-the-box events.
- Built-in analytics and Bayesian analysis for every variant and experience
- Seamless compatibility with your existing Sanity schemas
- Fast implementation with zero CMS migration
With Croct, any content already managed in Sanity becomes personalizable and ready for AB testing, without changing how you structure or deliver it.
Unlike currently available plugins, you can run experiments at the component level rather than the field level. Croct replaces static module content with dynamic content, allowing you to manage everything directly on the UI while using Sanity content as a fallback.
Since it comes with built-in audience segmentation and analytics, there's no need to add extra integrations with CDPs to segment visitors or with analytics tools to gather insights.
- A Sanity Studio (
studio/) with content types and sample data already onboard - A Next.js client (
frontend/) that fetches and renders the content from Sanity - Croct integration that makes Sanity content personalizable: the homepage hero is managed in Sanity and mapped to a Croct slot, and Croct takes over delivering the right variant to each visitor, falling back to the original Sanity content when no dynamic content applies
Follow these steps to run the project locally.
git clone https://github.com/croct-tech/croct-sanity-project.git
cd croct-sanity-project
npm installCreate the .env.local files from the templates:
cp studio/.env.example studio/.env.local
cp frontend/.env.example frontend/.env.localThen edit both files to fill in your Sanity project ID, dataset, and a read token (create one with Viewer permissions in Manage under API > Tokens).
Run the Croct CLI in the frontend directory to configure the application ID and API key automatically:
cd frontend
npx croct init
cd ..Import the sample content, including the personalizable hero section, into your Sanity dataset:
npm run import-sample-dataStart the Next.js app and the Sanity Studio together:
npm run devOpen http://localhost:3000 for the website and http://localhost:3333 for the Sanity Studio.
Adding Croct to an existing Sanity + Next.js project takes three small changes, with no restructuring of your content or pages required. Check the diff against the original template to see the exact changes.
1. Add the Croct proxy
// frontend/proxy.ts
export {proxy} from '@croct/plug-next/proxy';
export const config = {
matcher: '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
};2. Add the <CroctProvider>
// frontend/app/layout.tsx
import {CroctProvider} from '@croct/plug-next/CroctProvider';
<CroctProvider>{children}</CroctProvider>3. Fetch content with Sanity as fallback
The hero section is a regular Sanity document mapped to a Croct slot. When rendering the page, the content comes from Croct, using the original Sanity content as fallback:
// frontend/app/page.tsx
const fallback = await client.fetch(heroQuery, {slug: 'home-hero'});
const {content} = await fetchContent('home-hero@1', {
fallback: fallback ?? undefined,
});That's it. Once integrated, any content managed in Sanity becomes dynamic and ready for AB testing and personalization through Croct. Editing variants and targeting rules happens in Croct, with no code changes.
For more details on the tools used in this project, refer to the official documentation:
