For the complete documentation index, see llms.txt. Prefer markdown by appending.mdto documentation URLs or sendingAccept: text/markdown.
Usage
Evaluate feature flags in extension options and popup UI, sync targeting context from auth, and add new flag keys.
Once a provider is active, reading a flag is a one-liner with OpenFeature hooks from @workspace/flags.
Flag keys
Keys live in one place so web, mobile, and extension stay aligned:
export const Flag = {
DEMO: "demo",
} as const;Import Flag from @workspace/flags and pass the constant into hooks.
Evaluate in the UI
import { Flag, useBooleanFlagValue } from "@workspace/flags";
export const BetaNotice = () => {
const enabled = useBooleanFlagValue(Flag.DEMO, false);
if (!enabled) {
return null;
}
return <p>Beta features unlocked</p>;
};The options page uses the same pattern for the demo banner:
const DemoBanner = () => {
const demo = useBooleanFlagValue(Flag.DEMO, false);
if (!demo) {
return null;
}
// …
};Other value types:
| Hook | Typical use |
|---|---|
useBooleanFlagValue | On/off gates |
useStringFlagValue | Variant copy, theme names, URLs |
useNumberFlagValue | Limits, percentages, experiment arms |
useObjectFlagValue | Structured payloads / config blobs |
Always pass a sensible default as the second argument. That value is used while the provider loads, or if evaluation fails.
Targeting context
apps/extension/src/lib/providers/flags.tsx already syncs auth state into OpenFeature:
if (session.data?.user) {
const { id, email, name } = session.data.user;
void setContext({ targetingKey: id, email, name });
return;
}
void clearContext();You rarely need to call setContext / clearContext yourself. Import them from @workspace/flags-extension when you do.
With PostHog, context sync maps to identify / reset so person-based rules match your signed-in user.
Add a new flag
Declare the key
Add a constant in packages/flags/shared/src/keys.ts:
export const Flag = {
DEMO: "demo",
NEW_SIDE_PANEL: "NEW_SIDE_PANEL",
} as const;Update in-memory defaults
Give local development a known value in packages/flags/shared/src/in-memory.ts:
[Flag.NEW_SIDE_PANEL]: {
disabled: false,
variants: { on: true, off: false },
defaultVariant: "off",
},Create it remotely (if needed)
In PostHog or GrowthBook, create a flag with the same key (NEW_SIDE_PANEL). Configure rollouts and targeting there.
Evaluate it in the UI
const showSidePanel = useBooleanFlagValue(Flag.NEW_SIDE_PANEL, false);Troubleshooting
| Symptom | What to check |
|---|---|
| Demo banner never appears | In-memory defaultVariant is "on" by default. For PostHog/GrowthBook, ensure a remote flag named demo exists and targets your user. |
| Flag stuck on the default | Confirm the provider export in packages/flags/extension/src/providers/index.ts matches the env vars you set. Restart the Vite extension dev server after env changes. |
| Remote rules ignore the user | Sign in so targetingKey is set. Check PostHog person / GrowthBook attributes. |
| Wrong env prefix | Extension uses VITE_POSTHOG_* / VITE_GROWTHBOOK_*, not NEXT_PUBLIC_ or EXPO_PUBLIC_. |
How is this guide?
Last updated on