Lightweight split-testing library (A/B or multivariant)
npm install split-testing
npm install split-testing
`
Or through a CDN for having a global variable SplitTesting containing all the methods :
`html
`
Basic Usage
This is how you would use SplitTesting.js in ES6 to create an experiment:
`javascript
import { setExperiment } from 'split-testing';
const pickedVariant = setExperiment({
name: 'my-first-ab-test',
variants: [
{ name: 'control', data: {} },
{ name: 'test', data: {} }
]
})
`
There is only two options mandatory for setting up the experiment : name and variants.
The value returned by setExperiment is the variant that has been picked or retrieved in storage.
Real Usage
$3
By default the picked variant is saved in window.localStorage, but you can change that by defining your own storage property (see /src/types.ts for type definition).
For example, if you want to save the variant in cookies, you could do :
`javascript
import { setExperiment } from 'split-testing';
import Cookies from 'js-cookie'
const pickedVariant = setExperiment({
name: 'my-first-ab-test',
variants: [
{ name: 'control' },
{ name: 'test' }
],
storage: {
getItem(key) {
return Cookies.get(key) ?? null
},
setItem(key, value) {
Cookies.set(key, value, { expires: 365 })
},
removeItem(key) {
Cookies.remove(key)
}
}
})
`
This custom storage allows proper SSR with your JS framework, for example with NuxtJS 3 :
`javascript
storage: {
getItem(key) {
return useCookie(key)?.value ?? null
},
setItem(key, value) {
const currentDate = new Date()
const oneYearFromNow = new Date(currentDate.setFullYear(currentDate.getFullYear() + 1))
let newCookie = useCookie(key, { expires: oneYearFromNow })
newCookie.value = value
},
removeItem(key) {
let cookie = useCookie(key)
cookie.value = null
}
}
`
$3
By default all variants have the same probability of being picked at first load, but you can change that with the weight property :
`javascript
setExperiment({
name: 'abtest-weighted',
variants: [
{ name: 'control', weight: 0.50 }, // 50% chance of being picked
{ name: 'test1', weight: 0.25 }, // 25% chance of being picked
{ name: 'test2', weight: 0.25 } // 25% chance of being picked
]
})
`
To know - The weight values will be reseted in case of :
- The total of all weight is not equal to 1
- Some variants have a weight property and others no
In those cases, a warning will be logged into the console.
$3
For cross-device use, you can add a seed property, it will have for effect to always return the same variant.
`javascript
setExperiment({
name: 'my-first-ab-test',
variants: [
{ name: 'control' },
{ name: 'test' } // Always picked for the same user
],
seed: user.id
})
`
Warning: If a variant is already set (seeded or not) and a different seed from the variant's one is detected, then the variant will change for respecting the new seed. You can disallow this behavior by putting isResolvingSeedConflictAllowed: false in the options of setExperiment.
$3
If you want to send to your analytics provider the variant that has been picked, and that only one time (not the other times when the variant is simply retrieved from storage), you can use the onFirstPicking method.
Here is an example by sending the result of the experiment into Plausible Analytics :
`javascript
setExperiment({
name: 'my-first-ab-test',
variants: [
{ name: 'control' },
{ name: 'test' }
],
onFirstPicking: (pickedVariant) => {
Plausible.trackEvent('My first A/B test', {
variant: pickedVariant.name
})
}
})
`
$3
The debug mode will log various messages of information into the console, allowing you to better understand what the library is doing.
To activate it, simply add isDebugMode: true to the experiment options :
`javascript
setExperiment({
isDebugMode: true,
name: 'my-first-ab-test',
variants: [
{ name: 'control' },
{ name: 'test' }
]
})
`
$3
In case of error (bad configuration of the name and variants properties), setExperiment can purposefully throw errors, so the best is to write it inside a try / catch.
If the code doesn't throw an error in development mode, it shouldn't send one in production either.
Type definition
You can see the types of the library in the file src/types.ts.
For importing the types in your code, just do :
`typescript
import type { ExperimentOptions, Variant, Storage } from 'split-testing'
`
Todo before v1
- ~~Making a custom storage possible for having a SSR-friendly library~~
- Adding the removeExperiment` method for clearing the storage