# @se-studio/ab-testing — LLM Reference

Server-side A/B testing framework for Next.js App Router with Contentful CMS. Variants are assigned via cookies; decisions happen in Next.js middleware.

## Core Concepts

- **Test**: a named experiment with 2+ variants, each mapped to a URL path
- **Assignment**: a cookie that records which variant a user is seeing
- **Middleware**: intercepts requests and rewrites URLs to the assigned variant path

## Key Types

```ts
import type {
  AbTest,              // { id, name, variants: AbTestVariant[] }
  AbTestVariant,       // { id, name, path: string, weight: number }
  AbTestAssignment,    // { testId, variantId }
  AbTestCookie,        // serialised cookie value
  AbTestVariantConfig, // { variantId, contentPath }
  IBlobStore,          // storage interface for test configs (Vercel Blob)
} from '@se-studio/ab-testing';
```

## Middleware Setup

```ts
// middleware.ts
import { createAbTestMiddleware } from '@se-studio/ab-testing';

const abTestMiddleware = createAbTestMiddleware({
  blobStore,       // IBlobStore — fetches test configs from Vercel Blob
  cookieName: 'ab_assignment', // optional, default: DEFAULT_COOKIE_NAME
  cookieMaxAge: 60 * 60 * 24 * 30, // optional, default: DEFAULT_COOKIE_MAX_AGE
});

export async function middleware(request: NextRequest) {
  return abTestMiddleware(request);
}
```

For static (no blob store) tests:

```ts
import { createStaticAbTestMiddleware } from '@se-studio/ab-testing';

const abTestMiddleware = createStaticAbTestMiddleware({
  tests: [
    {
      id: 'hero-test',
      variants: [
        { id: 'control', path: '/home', weight: 50 },
        { id: 'variant-a', path: '/home-v2', weight: 50 },
      ],
    },
  ],
});
```

## Reading the Assignment (Client / Server)

```ts
import { useAbTestAssignments } from '@se-studio/ab-testing';

// In a React component:
const { assignments, isLoading } = useAbTestAssignments({ testIds: ['hero-test'] });
const variant = assignments['hero-test']; // AbTestAssignment | undefined
```

## Webhook Handler (Contentful → update test cache)

```ts
import { createWebhookHandler } from '@se-studio/ab-testing';

const handler = createWebhookHandler({
  blobStore,
  secret: process.env.WEBHOOK_SECRET!,
});

// In a Next.js route handler:
export const POST = handler.handle;
```

## Cookie Utilities

```ts
import {
  parseCookie,
  serializeCookie,
  readCookieFromDocument, // client-side
  DEFAULT_COOKIE_NAME,
  DEFAULT_COOKIE_MAX_AGE,
} from '@se-studio/ab-testing';
```

## Low-Level Utilities

```ts
import {
  selectVariant,       // weighted random variant selection
  getAssignment,       // read assignment from cookies
  setAssignment,       // write assignment to response cookies
  isValidAssignment,   // validate an assignment object
  normalizePath,       // normalise URL paths for comparison
  findCanonicalPath,   // resolve variant path back to canonical
} from '@se-studio/ab-testing';
```
