Skip to main content

React

Install the latest version

Use your favorite package manager to install @prefab-cloud/prefab-cloud-react npm | github

npm install @prefab-cloud/prefab-cloud-react

TypeScript types are included with the package.

Initialize the Client

This client includes a <PrefabProvider> and usePrefab hook.

First, wrap your component tree in the PrefabProvider, e.g.

import { PrefabProvider } from "@prefab-cloud/prefab-cloud-react";

const WrappedApp = () => {
const onError = (reason) => {
console.error(reason);
};

return (
<PrefabProvider apiKey={"YOUR_CLIENT_API_KEY"} onError={onError}>
<MyApp />
</PrefabProvider>
);
};

Feature Flags

Now use the usePrefab hook to fetch flags. isEnabled is a convenience method for boolean flags.

const Logo = () => {
const { isEnabled } = usePrefab();

if (isEnabled("new-logo")) {
return <img src={newLogo} className="App-logo" alt="logo" />;
}

return <img src={logo} className="App-logo" alt="logo" />;
};

You can also use get to access flags with other data types.

const { get } = usePrefab();

const flagVlaue = get("my-string-flag");

Using Context

contextAttributes lets you provide context that you can use to segment your users. Usually you will want to define context once when you setup PrefabProvider.

import { PrefabProvider } from "@prefab-cloud/prefab-cloud-react";

const WrappedApp = () => {
const contextAttributes = {
user: { key: "abcdef", email: "jeffrey@example.com" },
subscription: { key: "adv-sub", plan: "advanced" },
};

const onError = (reason) => {
console.error(reason);
};

return (
<PrefabProvider
apiKey={"YOUR_CLIENT_API_KEY"}
contextAttributes={contextAttributes}
onError={onError}
>
<App />
</PrefabProvider>
);
};

Dynamic Config

info

React is a Client SDK and does not receive Config. Learn more about Client SDKs

Testing

Wrap the component under test in a PrefabTestProvider and provide a config object to set up your test state.

e.g. if you wanted to test the following trivial component

function MyComponent() {
const { get, isEnabled, loading } = usePrefab();
const greeting = get("greeting") || "Greetings";

if (loading) {
return <div>Loading...</div>;
}

return (
<div>
<h1 role="alert">{greeting}</h1>
{isEnabled("secretFeature") && (
<button type="submit" title="secret-feature">
Secret feature
</button>
)}
</div>
);
}

You could do the following in jest/rtl

import { PrefabTestProvider } from "./index";

const renderInTestProvider = (config: { [key: string]: any }) => {
render(
<PrefabTestProvider config={config}>
<MyComponent />
</PrefabTestProvider>
);
};

it("shows a custom greeting", async () => {
renderInTestProvider({ greeting: "Hello" });

const alert = screen.queryByRole("alert");
expect(alert).toHaveTextContent("Hello");
});

it("shows the secret feature when it is enabled", async () => {
renderInTestProvider({ secretFeature: true });

const secretFeature = screen.queryByTitle("secret-feature");
expect(secretFeature).toBeInTheDocument();
});

Reference

usePrefab properties

const { isEnabled, get, loading, contextAttributes } = usePrefab();

Here's an explanation of each property

propertyexamplepurpose
isEnabledisEnabled("new-logo")returns a boolean (default false) if a feature is enabled based on the current context
getget('retry-count')returns the value of a flag or config
contextAttributes(see above)this is the context attributes object you passed when setting up the provider
tip

While loading is true, isEnabled will return false and get will return undefined.