Rollouts

This demo is easiest to understand if you open its source code in a parallel tab.

Source code

This demo shows how to use @happykit/flags for rollouts.

You can use flags to roll out features to a certain percentage of your users. Or you can use flags as the basis for your A/B-testing. This is all enabled by having the option to serve a variant to a certain percentage of incoming requests. We refer to this as percentage-based rollouts, or rollouts for short.

Rollouts work with any rendering strategy and you don't need to do anything special inside of @happykit/flags.

Setup

You can configure rollouts in rules or in the On default of your flag. Simply use the UI to specify which percentage of flag evaluations should be answered by which variant.

Note that configuring rollouts is only possible in the flag details after you created the flag. It is not possible when you first create a flag.

Splitting based on attributes

The percentage-based rollouts happen based on an attribute you specify when setting the rollout. You can use the visitorKey, any user attribute or any trait as the basis of the rollout.

Splitting on the same attribute value will always resolve to the same flag variant. A flag will resolve to null in case the attribute used as the base of splitting was not present on the request.

Example

When you first loaded this page, @happykit/flags generated a visitor key for you during server-side rendering. This key was then stored as a cookie in your browser by getFlags().

The purchaseButtonLabel flag is configured to do a rollout of "Purchase", "Buy now", "Add to cart" or "Get it" split evenly with 25% weight each.

If you refresh the page, you'll consistently see the same value. But if you repeatedly open the same page in a new Incognito Window, you'll see the four possible values alternate.

purchaseButtonLabel: "Purchase"
visitorKey: "6G2ZVH3C0uBtl5ad9Pao8"

Your purchaseButtonLabel is currently resolving to "Purchase" based on your visitorKey, which is set to 6G2ZVH3C0uBtl5ad9Pao8.

Render #1 (Current render)
{ flags: { ads: true, checkout: "short", discount: 5, purchaseButtonLabel: "Purchase" }, data: { flags: { ads: true, checkout: "short", discount: 5, purchaseButtonLabel: "Purchase" }, resolvedVariantIds: { ads: "on", checkout: "on", discount: "on", purchaseButtonLabel: "on" }, visitor: { key: "6G2ZVH3C0uBtl5ad9Pao8" } }, error: null, fetching: false, settled: true, visitorKey: "6G2ZVH3C0uBtl5ad9Pao8" }