#
Use feature flags
To use feature flags, start by following the setup LaunchDarkly integration guide to create and initialize a LaunchDarkly SDK client instance. Once the setup is complete, the examples below cover the most common use cases.
For more details, refer to the reference documentation.
#
Evaluate a feature flag in bootstrapping code
Once the LaunchDarkly SDK client is ready, feature flags can be evaluated in the bootstrapping code. To faciliate the evaluation of feature flags in non-React code, Squide offers a getFeatureFlag function:
import { getFeatureFlag } from "@squide/firefly";
// If the `enable-mixpanel` feature flag is not available, `true` will be returned.
const value = getFeatureFlag(launchDarklyClient, "enable-mixpanel", true);
#
Evaluate a feature flag in React code
To evaluate a feature flag in React, use the useFeatureFlag hook:
import { useFeatureFlag } from "@squide/firefly";
// If the `show-characters` feature flag is not available, `true` will be returned.
const value = useFeatureFlag("show-characters", true);
#
Register a conditionnal navigation item
To register a navigation item based on feature flags, refer to the register deferred navigation items guide.
#
Setup the typings
Before evaluating feature flags, modules must augment the FeatureFlags interface with the feature flags they intend to evaluate to ensure type safety and autocompletion.
First, create a types folder in the project:
project
├── src
├────── register.tsx
├────── Page.tsx
├────── index.tsx
├────── App.tsx
├── types
├────── feature-flags.d.ts
Then create an feature-flags.d.ts file:
import "@squide/firefly";
declare module "@squide/firefly" {
interface FeatureFlags {
// In the example above, the module only intends to evaliate the `show-characters` feature flag.
"show-characters": boolean;
}
}
Finally, update the project tsconfig.json to include the types folder:
{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json",
"types": [
"./types/feature-flags.d.ts"
]
},
"exclude": ["dist", "node_modules"]
}
If any other project using those environment variables must also reference the project's feature-flags.d.ts file:
{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json",
"types": [
"../another-project/types/feature-flags.d.ts"
]
},
"exclude": ["dist", "node_modules"]
}
Once configured, all feature flag hooks and functions are fully typed and support auto-completion:
#
Setup with tests
If the code under test uses environment variables, the FireflyRuntime instance can be used to mock these variables.
Considering the following page:
import { useFeatureFlag } from "@squide/firefly";
export function Page() {
const showCharacters = useFeatureFlag("show-characters", true);
return (
<>
<h1>Page!<h1>
{showCharacters && (
<ul data-testid="character-list">
<li>Maren Holt</li>
<li>Theo Calder</li>
<li>Inez Navarro</li>
</ul>
)};
</>
);
}
The following unit test can be written to mock the value of show-characters and test the ouput of the createTelemetryClient function:
import { FireflyProvider, FireflyRuntime, LaunchDarklyPlugin, InMemoryLaunchDarklyClient } from "@squide/firefly";
import {render, screen} from "@testing-library/react";
import type { ReactNode } from "react";
import { Page } from "./src/Page.tsx";
import "@testing-library/jest-dom";
test("when the \"show-characters\" feature flag is off, do not render the character list", () => {
const featureFlags = new Map([
["show-characters", false]
] as const);
const launchDarklyClient = new InMemoryLaunchDarklyClient(featureFlags);
const runtime = new FireflyRuntime({
plugins: [x => new LaunchDarklyPlugin(x, launchDarklyClient)]
});
render(
<FireflyProvider runtime={runtime}>
<Page />
</FireflyProvider>
);
expect(screen.queryByTestId("character-list")).not.toBeInTheDocument();
});
#
Setup with Storybook
To set up Storybook stories with feature flags, refer to the setup Storybook integration guide.