Browsers and React

Feature flags for web pages, with React hooks. No dependencies (React is optional).

Browsers can't be given an SDK key: it can read every flag's rules, including whatever they list (email addresses, user IDs). So a page uses the environment's client-side ID instead. It's public, fine in page source, and only lets the page ask the server for the values of flags marked Available to browsers, evaluated for the visitor the page names. The page never sees rules, segments or any other flag.

Values follow changes within about a second over a live stream (EventSource). If the server can't be reached, the last values stay in use.

Set up

  1. In the dashboard, open a flag and switch on Available to browsers.
  2. Under SDK keys, copy the environment's client-side ID (cli-…).
  3. Your Switchyard server must be reachable from your visitors' browsers.

Use it

ts
import { SwitchyardWebClient } from 'switchyard-web';

const flags = new SwitchyardWebClient({
  clientId: 'cli-…',
  baseUrl: 'https://flags.example.com',
  context: { key: user.id, attributes: { plan: user.plan } },
});

flags.isEnabled('new-checkout');               // false until values arrive, then the real value
flags.variation('checkout-button', 'green');   // text, number or JSON: the default's type must match

await flags.identify({ key: otherUser.id });   // after sign-in or sign-out
flags.onChange((keys) => rerender());

Values are worked out on the server for the context you send, so rules and percentage rollouts behave exactly as they do in server-side apps. The context comes from the browser: don't use browser flags for anything a visitor mustn't be able to switch on by changing it.

React

tsx
import { SwitchyardWebClient } from 'switchyard-web';
import { SwitchyardProvider, useFlag, useSwitchyard } from 'switchyard-web/react';

const flags = new SwitchyardWebClient({ clientId: 'cli-…', baseUrl, context: { key: user.id } });

root.render(
  <SwitchyardProvider client={flags}>
    <App />
  </SwitchyardProvider>,
);

function PayButton() {
  const color = useFlag('checkout-button', 'green'); // re-renders when it changes
  return <button style={{ background: color }}>Pay</button>;
}

useSwitchyard() gives the client (to call identify); useSwitchyardStatus() is starting until values arrive.

Options

Option Default
clientId required The environment's client-side ID
baseUrl http://localhost:8080 The Switchyard server
context {} Who's visiting: { key, attributes }
bootstrap none Values to use before the first answer, e.g. rendered by your server
streaming true Follow changes live (where EventSource exists)
pollInterval 60000 ms between checks when not streaming

Develop

bash
npm install
npm test        # client tests with a fake server, React hooks with react-dom/server
npm run build

The demo has a page using it: http://localhost:3000/browser.