@nimpl/ab-tests
A package for conducting A/B tests on a website using middleware. The package's API is inspired by the familiar APIs from next.js.
Installation
Using npm:
npm i @nimpl/ab-tests
How does this work
- The middleware will find a suitable test for which the request will match the given instructions.
- If the test is found, a
nimpl_ab
cookie will be added with a session lifetime (ifcookieLifeTime
is set - with a lifetime specified in this option). - Upon repeated requests, it will be checked whether the user still matches the test that was previously passed (considering the
ignoreOnNextRequests
option). If yes - the user will see the previously dropped version, otherwise - will try to participate in other tests.
Important
If cookieLifeTime
is not set - the user may not stop being a participant in the A/B test after closing the tab or browser.
A session may not end even after closing the browser and rebooting the system, depending on the browser and its settings.
Configuration
To start A/B testing, you need to create middleware by calling the createMiddleware function.
The function needs to be passed a list of tests (tests
) and the life time of the results cookie (cookieLifeTime
, in seconds):
import { type Test } from '@nimpl/ab-tests/dist/lib/types/tests';
import { createMiddleware } from '@nimpl/ab-tests';
const tests: Test[] = [
{
id: 'some-id',
source: '/',
variants: [
{
weight: 0.5,
destination: '/'
},
{
weight: 0.5,
destination: '/page-2'
}
],
}
]
export const middleware = createMiddleware({ tests, cookieLifeTime: 72400 });
Test options
Each test is described by the following keys:
id
- identifier of the current test, can be set to anything;
source
- the path the test will follow;
has
- array of rules that should be fulfilled for the user's request (more about rule options);
missing
- array of rules that should not be fulfilled for the user's request (more about rule options);
variants
- array of possible variants of the current test (more about variants).
Rule options
The user's request data are checked in accordance with the rules. The principles of the rules are similar to the rules of next.js.
Each rule may contain the following keys:
type
- the type of rule. Options: header
, cookie
, host
, query
;
key
- the key from the selected type to match against;
value
- the value that will be checked for the given key. If not specified - any value will be correct;
ignoreOnNextRequests
- ignore the rule when the test participant repeats the visit to the test page.
Variant
The test can have as many options as you like. The main condition is that the total probability of the options falling out should not exceed 1.
Each option is an object with keys:
destination
- the path where the option is located;
weight
- probability of the option being given (from 0 to 1);
type
- variant type - rewrite
or redirect
. Accordingly, when the option is triggered, either a rewrite will be performed or a redirect to the specified page will occur;
status
- response status when variant drops out.
Dynamic Data
Rules, just like in next.js, support dynamic data.
But, unlike next.js, this only works through regular expression variables (f.e. (?<param>.*)
).
Dynamic data can be obtained from source
or from value
of the rules. Then they can be embedded in destination tests:
{
id: 'some-id',
source: '/en-(?<country>de|fr|it)',
has: [
{
type: 'query',
key: 'ref',
value: 'utm_(?<ref>moogle|daybook)',
}
],
variants: [
{
weight: 0.5,
destination: '/en-:country/:ref'
},
{
weight: 0.5,
destination: '/en-:country/:ref/new'
}
],
}
Development
Read about working on the package and making changes on the contribution page
Additional
Please consider giving a star if you like it, it shows that the package is useful and helps continue work on this and other packages.
Create issues with wishes, ideas, difficulties, etc. All of them will definitely be considered and thought over.