ReactJS
This is a thin wrapper on top of the Javascript Library, so you might want to view those docs first to familiarize yourself with the basic classes and methods.
Installation
yarn add @growthbook/growthbook-react
or
npm install --save @growthbook/growthbook-react
Quick Usage
Step 1: Configure your app
import { useEffect } from "react";
import { GrowthBook, GrowthBookProvider } from "@growthbook/growthbook-react";
// Create a GrowthBook instance
const growthbook = new GrowthBook({
// Callback when a user is put into an A/B experiment
trackingCallback: (experiment, result) => {
console.log("Experiment Viewed", {
experimentId: experiment.key,
variationId: result.variationId,
});
},
});
export default function App() {
useEffect(() => {
// Load feature definitions from GrowthBook API
fetch("https://cdn.growthbook.io/api/features/<your api key>")
.then((res) => res.json())
.then((parsed) => {
growthbook.setFeatures(parsed.features);
});
// Set user attributes for targeting (from cookie, auth system, etc.)
growthbook.setAttributes({
id: "123",
company: "acme",
});
}, []);
return (
<GrowthBookProvider growthbook={growthbook}>
<OtherComponent />
</GrowthBookProvider>
);
}
Step 2: Start feature flagging!
There are a few ways to use feature flags in GrowthBook:
useFeature hook
import { useFeature } from "@growthbook/growthbook-react";
export default function OtherComponent() {
// Boolean on/off flags
const newLogin = useFeature("new-login-form").on;
// Multivariate or string/JSON values
const buttonColor = useFeature("login-button-color").value || "blue";
if (newLogin) {
return <NewLogin color={buttonColor} />;
} else {
return <Login color={buttonColor} />;
}
}
IfFeatureEnabled component
import { IfFeatureEnabled } from "@growthbook/growthbook-react";
export default function OtherComponent() {
return (
<div>
<h1>Hello!</h1>
<IfFeatureEnabled feature="welcome-message">
<p>Welcome to our site!</p>
</IfFeatureEnabled>
</div>
);
}
FeatureString component
import { FeatureString } from "@growthbook/growthbook-react";
export default function OtherComponent() {
return (
<div>
<h1>
<FeatureString feature="site-h1" default="My Site" />
</h1>
</div>
);
}
useGrowthBook hook
If you need low-level access to the GrowthBook instance for any reason, you can use the useGrowthBook
hook:
import { useGrowthBook } from "@growthbook/growthbook-react";
export default function OtherComponent() {
// Identical to: const feature = useFeature("my-feature")
const growthbook = useGrowthBook();
const feature = growthbook.feature("my-feature");
}
The GrowthBook Context
The GrowthBook
constructor takes a number of optional settings.
Features
If you already have features loaded as a JSON object, you can pass them into the constructor with the features
field:
new GrowthBook({
features: {
"feature-1": {...},
"feature-2": {...},
"another-feature": {...},
}
})
If you need to load feature definitions from a remote source like an API or database, you can update the context at any time with setFeatures()
(seen above in the Quick Start). Note - if you try to use a feature before it is loaded, it will always evaluate to null
.
If you use the GrowthBook App to manage your features, you don't need to build this JSON file yourself - it will auto-generate one for you and make it available via an API endpoint.
If you prefer to build this file by hand or you want to know how it works under the hood, check out the detailed Feature Definitions section in the Javascript SDK docs.
Attributes
You can specify attributes about the current user and request. These are used for two things:
- Feature targeting (e.g. paid users get one value, free users get another)
- Assigning persistent variations in A/B tests (e.g. user id "123" always gets variation B)
The following are some comonly used attributes, but use whatever makes sense for your application.
new GrowthBook({
attributes: {
id: "123",
loggedIn: true,
deviceId: "abc123def456",
company: "acme",
paid: false,
url: "/pricing",
browser: "chrome",
mobile: false,
country: "US",
},
});
If you need to set or update attributes asynchronously, you can do so with setAttributes()
. This will completely overwrite the attributes object with whatever you pass in. Also, be aware that changing attributes may change the assigned feature values. This can be disorienting to users if not handled carefully.
Tracking Callback
Any time an experiment is run to determine the value of a feature, we call a function so you can record the assigned value in your event tracking or analytics system of choice.
new GrowthBook({
trackingCallback: (experiment, result) => {
// Example using Segment.io
analytics.track("Experiment Viewed", {
experimentId: experiment.key,
variationId: result.variationId,
});
},
});
Feature Usage Callback
GrowthBook can fire a callback whenever a feature is evaluated for a user. This can be useful to update 3rd party tools like NewRelic or DataDog.
new GrowthBook({
onFeatureUsage: (featureKey, result) => {
console.log("feature", featureKey, "has value", result.value);
},
});
The result
argument is the same thing returned from the useFeature
hook.
Note: If you evaluate the same feature multiple times (and the value doesn't change), the callback will only be fired the first time.
Inline Experiments
Depending on how you configure feature flags, they may run A/B tests behind the scenes to determine which value gets assigned to the user.
Sometimes though, you want to run an inline experiment without going through a feature flag first. For this, you can use either the useExperiment
hook or the Higher Order Component withRunExperiment
:
useExperiment hook
import { useExperiment } from "@growthbook/growthbook-react";
export default function OtherComponent() {
const { value } = useExperiment({
key: "new-headline",
variations: ["Hello", "Hi", "Good Day"],
});
return <h1>{value}</h1>;
}
Class Components
Note: This library uses hooks internally, so still requires React 16.8 or above.
import { withRunExperiment } from "@growthbook/growthbook-react";
class OtherComponent extends React.Component {
render() {
// The `runExperiment` prop is identical to the `useExperiment` hook
const { value } = this.props.runExperiment({
key: "headline-test",
variations: ["Hello World", "Hola Mundo"],
});
return <h1>{value}</h1>;
}
}
// Wrap your component in `withRunExperiment`
export default withRunExperiment(OtherComponent);