Skip to content

A fast and lightweight AB-Testing library for React and Next.js based on hooks and functional components. Full Typescript support and result caching is possible.

Notifications You must be signed in to change notification settings

NiklasMencke/react-ab-test-hooks

Repository files navigation

react-ab-test-hooks

A fast and lightweight AB-Testing library for React and Next.js based on hooks and functional components. Full Typescript support and result caching is possible.

NPM JavaScript Style Guide

Install

yarn add react-ab-test-hooks

or

npm install --save react-ab-test-hooks

Basic Usage

A simple usage example for an AB-Test would be to pass each respective React Element/Component directly in the Experiment's variants. The experiment hook will then chose a winner and return it as Variant, which can then be used in your UI.

Per default the result is not cached, meaning on every new page load, the experiment is run again. You can enable caching by passing: cacheResult: true.

Per default the weight distribution is equal among all variants provided in the experiment. If you wan't to provide a custom probability distribution, you can do so via weights: [0.3, 0.7].

See further examples for more options.

import React from 'react'

import { useExperiment, useExperimentWrappers } from 'react-ab-test-hooks'

export const SimpleExample = () => {
  const { SelectedVariant } = useExperiment({
    id: 'experiment-1',
    variants: [
      { id: 'A', element: <div>Variant A won</div> },
      { id: 'B', element: <div>Variant B won</div> }
    ],
    onResult: (experimentId, selectedVariant) =>
      console.log(
        `Experiment ${experimentId} finished. Selected Variant ID: ${selectedVariant.id}`
      )
  })

  return (
    <div className='wrapper'>
      <SelectedVariant />
    </div>
  )
}

Generate variant wrapper components (+ result caching)

It's also possible to retrieve wrappers (as functional components) for each variant provided. In contrary to above example this would mean that in any case you will receive a wrapper for each variant and only the winning variant will actually render it's children. This can be convinient if you wanna render a more complex UI based on the experiment result. You can extract the Wrapper Components via array destructering.

NOTE: Only the children of the winning variant wrapper are rendered!

import React from 'react'

import { useExperiment, useExperimentWrappers } from 'react-ab-test-hooks'

export const WrapperExample = () => {
  const {
    wrappers: [VariantA, VariantB, VariantC] // Extract the wrapper components here
  } = useExperimentWrappers({
    id: 'experiment-2',
    variants: [{ id: 'A' }, { id: 'B' }, { id: 'C' }], // more than 2 variants are possible
    cacheResult: true,
    onResult: (experimentId, selectedVariant) =>
      console.log(
        `Experiment ${experimentId} finished. Selected Variant Wrapper ID: ${selectedVariant.id}`
      )
  })

  return (
    <div className='wrapper'>
      <VariantA>Variant A won experiment</VariantA>
      <VariantB>Variant B won experiment</VariantB>
      <VariantC>Variant C won experiment</VariantC>
    </div>
  )
}

With custom probability distribution

import React from 'react'

import { useExperiment, useExperimentWrappers } from 'react-ab-test-hooks'

export const CustomWeightsExample = () => {
  const { SelectedVariant } = useExperiment({
    id: 'experiment-3',
    variants: [
      { id: 'A', element: <div>Variant A won</div> },
      { id: 'B', element: <div>Variant B won</div> }
    ],
    weights: [0.3, 0.7], // Has to add up to 1.0 and has to have the same length as the variant array
    cacheResult: false,
    onResult: (experimentId, selectedVariant) =>
      console.log(
        `Experiment ${experimentId} finished. Selected Variant ID: ${selectedVariant.id}`
      )
  })

  return (
    <div className='wrapper'>
      <SelectedVariant />
    </div>
  )
}

Error handling example

import React from 'react'

import { useExperiment, useExperimentWrappers } from 'react-ab-test-hooks'

export const ErrorExample = () => {
  const { SelectedVariant, error } = useExperiment({
    id: 'experiment-4',
    variants: [
      { id: 'A', element: <div>Variant A won</div> },
      { id: 'B', element: <div>Variant B won</div> }
    ],
    weights: [0.3], // distribution incorrect -> returns error
    cacheResult: false,
    onResult: (experimentId, selectedVariant) =>
      console.log(
        `Experiment ${experimentId} finished. Selected Variant ID: ${selectedVariant.id}`
      )
  })

  if (error) {
    console.log(error)
    return null
  }

  return (
    <div className='wrapper'>
      <SelectedVariant />
    </div>
  )
}

Support

If you like this library it would be amazing if you would give it a star :)

License

MIT © NiklasMencke

API Documentation

Find the detailed API documentation attached.

Interfaces

react-ab-test-hooks / Exports / UseExperimentProps

Interface: UseExperimentProps

Hierarchy

  • ExperimentBaseProps

    UseExperimentProps

Table of contents

Properties

Properties

cacheResult

Optional cacheResult: boolean

Optional: Boolean that indicates if the experiment result should be cached to the browsers local storage. This will ensure, that once an experiment is finished, the user will always sees the same variant. Example: true

Inherited from: void

Defined in: index.tsx:23


id

id: string

Experiment ID. Example: 'experiment-1'

Inherited from: void

Defined in: index.tsx:19


onResult

Optional onResult: (experimentId: string, selectedVariant: Variant | VariantWrapper) => null | void

Optional: Callback function that is called when the experiment has been finished and a variant was selected.

Type declaration:

▸ (experimentId: string, selectedVariant: Variant | VariantWrapper): null | void

Parameters:
Name Type
experimentId string
selectedVariant Variant | VariantWrapper

Returns: null | void

Defined in: index.tsx:25

Inherited from: void

Defined in: index.tsx:25


variants

variants: Variant[]

An array of variants. Has to contain at least two items

Defined in: index.tsx:30


weights

Optional weights: number[]

Optional: Weight distribution as a number array. Has to match the length of the variant array. Defaults to equal distribution. E.g. [0.5, 0.5]

Inherited from: void

Defined in: index.tsx:21

react-ab-test-hooks / Exports / UseExperimentResponse

Interface: UseExperimentResponse

Table of contents

Properties

Properties

SelectedVariant

SelectedVariant: FC<{}>

The selected variant that won the experiment and was chosen from the previously passed variants.

Defined in: index.tsx:56


error

Optional error: null | string

Error string that is filled in case something breaks

Defined in: index.tsx:60


onResult

Optional onResult: (experimentId: string, selectedVariant: Variant) => null | void

Callback function that is called when the experiment has been finished and a variant was selected.

Type declaration:

▸ (experimentId: string, selectedVariant: Variant): null | void

Parameters:
Name Type
experimentId string
selectedVariant Variant

Returns: null | void

Defined in: index.tsx:58

Defined in: index.tsx:58

react-ab-test-hooks / Exports / UseExperimentWrapperProps

Interface: UseExperimentWrapperProps

Hierarchy

  • ExperimentBaseProps

    UseExperimentWrapperProps

Table of contents

Properties

Properties

cacheResult

Optional cacheResult: boolean

Optional: Boolean that indicates if the experiment result should be cached to the browsers local storage. This will ensure, that once an experiment is finished, the user will always sees the same variant. Example: true

Inherited from: void

Defined in: index.tsx:23


id

id: string

Experiment ID. Example: 'experiment-1'

Inherited from: void

Defined in: index.tsx:19


onResult

Optional onResult: (experimentId: string, selectedVariant: Variant | VariantWrapper) => null | void

Optional: Callback function that is called when the experiment has been finished and a variant was selected.

Type declaration:

▸ (experimentId: string, selectedVariant: Variant | VariantWrapper): null | void

Parameters:
Name Type
experimentId string
selectedVariant Variant | VariantWrapper

Returns: null | void

Defined in: index.tsx:25

Inherited from: void

Defined in: index.tsx:25


variants

variants: VariantWrapper[]

An array of variants. Has to contain at least two items. The element attribute is left out here.

Defined in: index.tsx:35


weights

Optional weights: number[]

Optional: Weight distribution as a number array. Has to match the length of the variant array. Defaults to equal distribution. E.g. [0.5, 0.5]

Inherited from: void

Defined in: index.tsx:21

react-ab-test-hooks / Exports / UseExperimentWrapperResponse

Interface: UseExperimentWrapperResponse

Table of contents

Properties

Properties

error

Optional error: null | string

Error string that is filled in case something breaks

Defined in: index.tsx:51


onResult

Optional onResult: (experimentId: string, selectedVariantId: VariantWrapper) => null | void

Callback function that is called when the experiment has been finished and a variant was selected.

Type declaration:

▸ (experimentId: string, selectedVariantId: VariantWrapper): null | void

Parameters:
Name Type
experimentId string
selectedVariantId VariantWrapper

Returns: null | void

Defined in: index.tsx:49

Defined in: index.tsx:49


wrappers

wrappers: FC<{}>[]

An array containing a wrapper component for each of the previously passed variants. Only the Variant Wrapper that won will render it's children.

Defined in: index.tsx:47

react-ab-test-hooks / Exports / UseVariantProps

Interface: UseVariantProps

Hierarchy

  • ExperimentBaseProps

    UseVariantProps

Table of contents

Properties

Properties

cacheResult

Optional cacheResult: boolean

Optional: Boolean that indicates if the experiment result should be cached to the browsers local storage. This will ensure, that once an experiment is finished, the user will always sees the same variant. Example: true

Inherited from: void

Defined in: index.tsx:23


id

id: string

Experiment ID. Example: 'experiment-1'

Inherited from: void

Defined in: index.tsx:19


onResult

Optional onResult: (experimentId: string, selectedVariant: Variant | VariantWrapper) => null | void

Optional: Callback function that is called when the experiment has been finished and a variant was selected.

Type declaration:

▸ (experimentId: string, selectedVariant: Variant | VariantWrapper): null | void

Parameters:
Name Type
experimentId string
selectedVariant Variant | VariantWrapper

Returns: null | void

Defined in: index.tsx:25

Inherited from: void

Defined in: index.tsx:25


type

type: standard | wrapper

The type of variant. 'wrapper' will result in returning wrapper components for each variant of the experiment. Example: 'standard'

Defined in: index.tsx:42


variants

variants: (Variant | VariantWrapper)[]

An array of variants

Defined in: index.tsx:40


weights

Optional weights: number[]

Optional: Weight distribution as a number array. Has to match the length of the variant array. Defaults to equal distribution. E.g. [0.5, 0.5]

Inherited from: void

Defined in: index.tsx:21

react-ab-test-hooks / Exports / Variant

Interface: Variant

Table of contents

Properties

Properties

element

element: any

React Node to render if this variant succeeds. Can be a React Component or HTML. Example:

Variant A

Defined in: index.tsx:9


id

id: string

Variant ID. Example: 'variant-a'

Defined in: index.tsx:7

react-ab-test-hooks / Exports / VariantWrapper

Interface: VariantWrapper

Table of contents

Properties

Properties

id

id: string

Variant ID. Example: 'variant-a'

Defined in: index.tsx:14

react-ab-test-hooks / Exports

react-ab-test-hooks

Table of contents

Interfaces

Functions

Functions

useExperiment

ConstuseExperiment(__namedParameters: UseExperimentProps): UseExperimentResponse

A hook that takes an AB-Test experiment configuration and choses a variant that won the experiment based on a probability distribution. The probably distribution can be defined in the weights array (e.g [0.1, 0.9]). It defaults to an even distribution. it will return the variant (as a React Element) that won the given experiment.

Parameters:

Name Type
__namedParameters UseExperimentProps

Returns: UseExperimentResponse

The Variant component that won the experiment.

Defined in: index.tsx:194


useExperimentWrappers

ConstuseExperimentWrappers(__namedParameters: UseExperimentWrapperProps): UseExperimentWrapperResponse

A hook that takes an AB-Test experiment configuration and choses a variant that won the experiment based on a probability distribution. The probably distribution can be defined in the weights array (e.g [0.1, 0.9]). It defaults to an even distribution. it will return wrapper components for each variant provided in the variants parameter in props. Only the wrapper for the variant that won the experiment will display its children.

Parameters:

Name Type
__namedParameters UseExperimentWrapperProps

Returns: UseExperimentWrapperResponse

An array containing wrapper components for each variant provided in this experiment.

Defined in: index.tsx:222

About

A fast and lightweight AB-Testing library for React and Next.js based on hooks and functional components. Full Typescript support and result caching is possible.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published