DocsSDKReact / Next.js

React / Next.js

Two packages work together — pick what you need:

PackageUse for
@koryla/nextFull-page routing (//variant-b) via Next.js middleware
@koryla/reactComponent-level testing within a single page

The live demo uses the middleware approach — three experiments running on /headline, /hero, and /pricing.


@koryla/next — Full-page middleware

The simplest path. No changes to your pages — the middleware intercepts requests and rewrites the URL before Next.js renders anything.

Next.js demo: middleware.ts — the complete middleware setup used in the demo, intercepting /headline, /hero, and /pricing.

Install

npm install @koryla/next

middleware.ts

Next.js demo: app/headline/page.tsx and app/headline-b/page.tsx — control and variant pages for a text-change experiment.

import { korylaMiddleware } from '@koryla/next'

export default korylaMiddleware({
  apiKey: process.env.KORYLA_API_KEY!,
  apiUrl: process.env.KORYLA_API_URL!,
})

export const config = {
  matcher: ['/', '/pricing', '/landing'],  // paths to A/B test
}

.env.local

KORYLA_API_KEY=sk_live_...
KORYLA_API_URL=https://koryla.com

That's it. Create variants in your dashboard, point them to /your-page-v2, and Koryla handles the rest.


@koryla/react — Component-level testing

Test a specific section within a page — CTA copy, hero image, pricing layout — without routing to a different URL.

Install

npm install @koryla/react

1. Create a shared client

// lib/koryla.ts
import { createKoryla } from '@koryla/react'

export const koryla = createKoryla({
  apiKey: process.env.KORYLA_API_KEY!,
  apiUrl: process.env.KORYLA_API_URL!,
})

2. Use in a Server Component

// app/page.tsx
import { headers } from 'next/headers'
import { koryla } from '@/lib/koryla'
import { Experiment, Variant } from '@koryla/react'

export default async function Page() {
  const result = await koryla.getVariant(
    'your-experiment-id',
    headers().get('cookie') ?? '',
  )

  return (
    <main>
      <Experiment variantId={result?.variantId ?? ''}>
        <Variant id="control">
          <h1>Original headline</h1>
        </Variant>
        <Variant id="variant-b">
          <h1>New headline — does it convert?</h1>
        </Variant>
      </Experiment>
    </main>
  )
}

Use @koryla/next alongside — it handles cookie setting automatically. Or set it manually in a route handler:

if (result?.isNewAssignment) {
  response.cookies.set(result.cookieName, result.variantId, {
    maxAge: 60 * 60 * 24 * 30,
    sameSite: 'lax',
    path: '/',
  })
}

Environment variables

VariableValue
KORYLA_API_KEYYour sk_live_... key from Settings → API Keys
KORYLA_API_URLhttps://koryla.com