SDK
Nuxt SDK
Reference for @obelism/improve-sdk-nuxt: the server middleware for server-side A/B tests in Nuxt.
The Nuxt SDK sits around the Javascript Server SDK and gives Nuxt a server middleware for Nitro (Nuxt 3 and 4).
Install
npm i @obelism/improve-sdk-nuxtGenerator
The main export generates the middleware from the passed configuration. Export it from a file in server/middleware/.
import { ImproveServerSDK } from '@obelism/improve-sdk/server'
import { generateImproveNuxtMiddleware } from '@obelism/improve-sdk-nuxt'
export default generateImproveNuxtMiddleware({
improveSdk: new ImproveServerSDK(IMPROVE_ARGS),
serverABtests: [],
})improveSdk
generateImproveNuxtMiddleware({
improveSdk: ImproveServerSDK,
})The ImproveServerSDK to be used. The middleware fetches its datafile on the first request a server instance gets, once for concurrent requests, and keeps it: a test changed after that reaches the instance when it restarts or through a deploy. Pages wait for that fetch, so set configRetries: 0 (and a fetchTimeout) to fail fast; without a datafile the page renders without a decision.
serverABtests
generateImproveNuxtMiddleware({
serverABtests: ServerABTestConfig[]
})Not every A/B test from the config needs to be decided on the server. Each entry in this list is one server side test:
export type ServerABTestConfig = {
// Needs to match an A/B test in Improve
slug: string
// The page route to decide it on: a path (`/`), a parameter
// (`/products/[id]`) or a catch-all (`/blog/[...slug]`)
routeHandler: string
}Parameters match letters, digits and -; optional parameters ([[id]]) don't match. With app.baseURL set, include it. Several tests can share a route.
options
generateImproveNuxtMiddleware({
options?: {
visitorId?: CookieOptions
testValue?: CookieOptions
}
})Optional overrides for the cookies the middleware reads and writes. visitorId customizes the obelism_visitor_id cookie and testValue the per-test value cookie: both accept h3's setCookie options (maxAge, path, domain, secure, sameSite, …). Defaults: path: '/' and a week. Keep them readable from JavaScript (no httpOnly): the client SDK reads them. The middleware still reads the old visitorId cookie, so existing visitors keep their id.
The middleware
For a page request on a route with a server test, the middleware decides on one of three reasons:
- A query parameter named after the test with a valid option (
/?startpage-visual=variation). Recommended for development or testing purposes; it shouldn't be used for real users since it impacts the distribution. - The test's cookie, when it names a valid option. The middleware both reads and writes this cookie.
- A new decision for the visitor (from the
obelism_visitor_idcookie, or a new id). On a long-running server theImproveServerSDKalso remembers a visitor's decision in memory; on serverless or edge it can't.
It leaves bots, non-GET requests, Nuxt's own requests (/_nuxt/, /__nuxt_error, payloads), /api/ and files alone. A page it decided for gets Cache-Control: private.
getImproveContext
const variants: Record<string, string> = getImproveContext(event)The variants the middleware decided for this request, by test slug (also on event.context.improve). Empty for a bot, a route without a server test, or without a datafile. In a page, read it from useRequestEvent() into useState; see Nuxt.
Country targeting
The middleware reads the visitor's country from the edge geo headers (Vercel's x-vercel-ip-country, falling back to Cloudflare's cf-ipcountry) and passes it into the server SDK's bucketing as the geo argument. So audiences that target country resolve automatically for server side tests, with no extra code. Because the browser can't determine country from the user agent, this server-side pass is the only place a country audience is evaluated; the middleware writes the resulting variant to the test cookie, which the client SDK then honors.