Browser and React

Read public flags in the browser with @coframe/sdk/feature-flags and the React hooks in @coframe/sdk/react

Guide~3 min read

Copy this guide and your current settings as a prompt for your AI agent.

Preview agent promptSee the guide, code and settings included when you copy.

Flags are separate npm entry points of @coframe/sdk (1.1.24 or newer). The cf.js script tag does not contain them, and nothing is fetched, cached or listened to until featureFlags.init() runs. The browser only ever receives public flags; see Public and private.

BASH
npm install @coframe/sdk
On this page
  1. 01Browser
  2. 02React

01Browser

TS
import { setUserToken } from '@coframe/sdk'
import {
  featureFlags,
  isFeatureEnabled,
  getFeatureFlag,
  getFeatureFlagPayload,
  onFeatureFlags,
} from '@coframe/sdk/feature-flags'

setUserToken('customer-123') // your stable user id

await featureFlags.init({
  projectId: 'your-project-id',
  selector: { names: ['checkout-redesign'], groups: ['homepage_campaigns'] },
})

onFeatureFlags(() => {
  if (isFeatureEnabled('checkout-redesign')) showNewCheckout()
  const layout = getFeatureFlag('checkout-layout') // 'control' | 'compact' | …
  const content = getFeatureFlagPayload('homepage-content')
})
Function Returns
featureFlags.init(options) Starts loading. options: projectId (required), userToken, userContext, selector, consent, reloadOnSpaNavigation (default true), requestTimeoutMs (default 3000), cacheTtlMs (default 5 minutes)
isFeatureEnabled(key) true when a toggle is on or a variant is assigned; false otherwise; undefined before results land
getFeatureFlag(key) true/false for a toggle, the variant key for a variant flag, undefined before results land
getFeatureFlagPayload(key) The flag’s payload, or the assigned variant’s payload
getRemoteConfig(key) Same as getFeatureFlagPayload, named for remote config
getFeatureFlagResult(key) The full result: enabled, reason, variant, payload, metadata.version
onFeatureFlags(callback) Runs when results arrive or change; returns an unsubscribe function
reloadFeatureFlags() Re-evaluates now
setUserToken(token), getUserToken(), reset(), setConsent(enabled) Identity and consent, also exported from @coframe/sdk/feature-flags

How the browser behaves

Behaviour Detail
Timeout 3 s by default (requestTimeoutMs). Loading never delays the page
Cache localStorage key coframe.featureFlags.<projectId>, 5 minutes (cacheTtlMs), written only after consent, keyed by a hash of token and context. A fresh cached answer shows immediately; a failed fetch falls back to it
SPA navigation Re-evaluates on pushState, replaceState, popstate and hashchange because conditions can target the URL. Turn off with reloadOnSpaNavigation: false
Identity change setUserToken clears results and fetches again

Who is this visitor?

Rollouts and variant splits hash the user token, so give every user a stable one. In the browser the first match wins:

  1. init({ userToken })
  2. the latest queued setUserToken() (also window.CFQ.push({ setUserToken }))
  3. the coframe.user.token cookie
  4. a new random UUID

The cookie is only written after consent (setConsent(true) or window.CFQ.push({ cookiesEnabled: true })). Before consent a generated token changes on every page load, so a 10 % rollout can answer differently each time. Pass your own user or session id whenever you have one.

02React

TSX
import { featureFlags } from '@coframe/sdk/feature-flags'
import { useFeatureFlag, useFeatureFlagPayload } from '@coframe/sdk/react'

featureFlags.init({ projectId: 'your-project-id' }) // once, at startup

function Checkout() {
  const enabled = useFeatureFlag('checkout-redesign')
  const config = useFeatureFlagPayload('checkout-redesign')
  if (enabled === undefined) return <CheckoutSkeleton />
  return enabled ? <NewCheckout config={config} /> : <OldCheckout />
}
Hook Returns
useFeatureFlagEnabled(key) boolean | undefined
useFeatureFlagVariantKey(key), alias useFeatureFlag(key) true/false for a toggle, the variant key for a variant flag, undefined before load
useFeatureFlagPayload(key) The payload, or the assigned variant’s payload
useFeatureFlagResult(key) The full result object

The hooks read the same state as @coframe/sdk/feature-flags. CoframeProvider does not start flag loading on its own: call featureFlags.init once.

Multiple variants in code

TS
const layout = getFeatureFlag('checkout_experience_v1') // "standard" | "compact" | "express" | false | undefined
const config = getFeatureFlagPayload('checkout_experience_v1') // { layout: "compact", cta: "Finish checkout" }

isFeatureEnabled(key) is true whenever a variant is assigned. Variants are not linked to Coframe experiments: no exposure events are sent and nothing appears in experiment reporting. Use a Coframe experiment when you need measured impact.

Related reading

Content and video lessons from Coframe documentation. Code examples are not executed on this page.

BACK TOFeature Flags

Documentation

Open Coframe App

Search documentation

Search all guides and references↑ ↓ Navigate · Esc Close