Skip to content
 
 

Repository files navigation

Storyblok + Croct

Storyblok demo with personalization and AB testing

A Next.js 16 storefront powered by Storyblok for content management
and Croct for real-time personalization.

Live demo


Background

Storyblok published a great tutorial on personalization with Next.js that walks through building personalized experiences using cookies, middleware rewrites, and manually defined content variants. It's a solid starting point for understanding the concepts.

In practice, though, that approach requires custom code for every new audience segment, manual variant wiring in the CMS, and has no built-in support for AB testing or analytics. As the number of pages and segments grows, it becomes hard to maintain.

This project is a fork of the original demo that replaces the manual personalization logic with Croct. With Croct, any content already managed in Storyblok becomes personalizable and ready for AB testing, without changing how you structure or deliver your pages.

What is Croct?

Croct is a headless platform for conversion optimization that pairs nicely with Storyblok. Using Croct, you get:

With Croct, any content already managed in Storyblok 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 Storyblok 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.

What is inside this demo?

A fashion store demo that shows how Storyblok and Croct work together in a Next.js App Router project. Storyblok manages all the content, while Croct makes it personalizable and trackable without any changes to the content structure.

  • CMS-managed pages — announcement bar, homepage hero, feature strips, split features, and product catalog are all Storyblok stories
  • Personalized content — Croct delivers targeted variants for any Storyblok component, with no extra CMS configuration
  • Interest tracking — browsing behavior (category views, style quiz answers) is captured in real-time to build user profiles
  • Event-driven analytics — funnel events like cart views, checkouts, and purchases are tracked through Croct for personalization and analytics
  • Concierge widget — an interactive style quiz that collects preferences and feeds them into Croct for immediate personalization

How to get started?

Follow these steps to run the project locally. You'll need access to a Storyblok space and optionally a Croct workspace.

Prerequisites

  • Node.js 18+
  • A Storyblok space with the demo content
  • A Croct workspace (or use the pre-configured one)

1. Clone and install

git clone <repo-url>
cd storyblok-next-personalization
npm install

2. Set up Storyblok

Create a .env.local file with your Storyblok access token:

NEXT_PUBLIC_STORYBLOK_CONTENT_API_ACCESS_TOKEN=<your-token>

3. Set up Croct

Run the Croct CLI to configure the app ID and API key automatically:

npx croct init

4. Run

npm run dev

Open http://localhost:3000.

How does the integration work?

Adding Croct to an existing Storyblok + Next.js project takes three small changes — no restructuring of your content or pages required. Check the commit history to see the exact diff.

1. Wrap the Storyblok init with withCroct

// lib/storyblok.ts
import {withCroct} from '@croct/plug-storyblok/next';

export const getStoryblokApi = storyblokInit(withCroct({
    accessToken: '...',
    use: [apiPlugin],
    components: { ... },
}));

2. Add the <CroctProvider>

// app/layout.tsx
import {CroctProvider} from '@croct/plug-next/CroctProvider';

<CroctProvider>
    {children}
</CroctProvider>

3. Export the proxy middleware

// proxy.ts
export {proxy} from '@croct/plug-next/proxy';

That's it. No extra config, no migration. Once integrated, any content managed in Storyblok becomes personalizable and ready for AB testing and personalization through Croct.

For the full integration guide, see the Storyblok SDK documentation.

Project structure

The project follows a standard Next.js App Router layout. The integration-relevant parts are organized as follows:

  • lib/storyblok.ts — Storyblok SDK initialization wrapped with withCroct to enable personalization on all stories
  • app/layout.tsx — Root layout with <CroctProvider> and <StoryblokProvider>
  • proxy.ts — Exports the Croct proxy middleware for server-side personalization
  • components/blocks/ — Storyblok content block components (hero, catalog, announcement bar, feature strips, etc.), each using storyblokEditable for visual editing

Event tracking

The app tracks user behavior across the entire funnel through Croct, enabling personalization rules and analytics based on real interactions.

Event Trigger Source
cartViewed Page loaded /cart
cartModified Item added, removed, or updated /cart
checkoutStarted Page loaded /checkout
orderPlaced Order confirmed /confirmation
interestShown Category page viewed /catalog/[category]
interestShown Quiz answer selected Site-wide
leadGenerated Newsletter subscribed /
userSignedUp Account created /signin
goalCompleted Hero CTA clicked /
goalCompleted Announcement bar clicked /
goalCompleted Item added to cart /product/[slug]
goalCompleted Coupon redeemed /cart
goalCompleted Checkout started /checkout
goalCompleted Purchase completed /confirmation
goalCompleted Newsletter subscribed /
goalCompleted Account created /signin
goalCompleted Concierge started Site-wide
goalCompleted Concierge completed Site-wide

Deploying

The project is ready to deploy on any platform that supports Next.js. Click the button below to deploy directly to Vercel.

Deploy with Vercel

Make sure to set the environment variables listed above in your hosting provider's dashboard.

Docs

For more details on the tools used in this project, refer to the official documentation: