Getting started
NextJS
Run A/B tests in Next.js middleware, so the variant is decided before the page renders. No layout shift.
Within the client side application the React SDK will do everything you need it to do. If you are only running your AB tests client side, you don't need this package. However NextJS also provides a setup for server routing where you might also want to use AB testing.
This package is for Next.js middleware only. On React Router, and on Shopify Oxygen, the loader decides instead: see React Router.
When to use
A good scenario to use this is when you want to AB test part of a single page, above the fold. Like on the homepage of Improve. If we'd use a client side test for this there would be layout shift since the first paint would need to be the same. This can have a negative impact on alternative versions. That's why we need a server side AB test, this way the server can detect what version the visitor would get and the first paint will match your version.
How it works
To not get in the way of how you render your pages; static/dynamic or somewhere in between. The Improve NextJS SDK will sit in the middleware, this way it can rewrite to different internal routes based on cookie values or query parameters.
Install
npm i @obelism/improve-sdk-nextMiddleware
Within the middleware you can create the handler by passing it the Improve SDK and a list of the AB tests that you want to server side test.
For each server AB test you need to specify the route it needs to run on and the internal slugs you want to rewrite visitors to. For more complicated rewrites it's possible to provide a formatSlug function.
import type { NextRequest } from 'next/server'
import { ImproveServerSDK } from '@obelism/improve-sdk/server'
import { generateImproveNextMiddleware } from '@obelism/improve-sdk-next'
export const config = {
matcher: '/',
}
const improveSdk = new ImproveServerSDK({
organizationId: process.env.NEXT_PUBLIC_IMPROVE_ORG_ID,
environment: process.env.NEXT_PUBLIC_IMPROVE_ENV,
})
const improveMiddlewareHandler = generateImproveNextMiddleware({
improveSdk,
serverABtests: [
{
slug: 'startpage-visual',
routeHandler: '/',
options: [
{
value: 'control',
slug: '/',
},
{
value: 'variation',
slug: '/variation',
},
],
},
],
})
export const middleware = async (request: NextRequest) => {
await improveSdk.fetchConfig()
return improveMiddlewareHandler(request)
}