Skip to content

Web quickstart

In a few minutes your website will read a real feature flag — with a durable cache, a fail-safe answer for every situation, and nothing for you to manage in the browser.

Zero runtime dependencies; the whole SDK rides under a 10 kB gzip ceiling.

The SDK is pre-release and isn’t published to npm yet. If your team has been given access to the repository (FortressFlag_SDK_web), build it with pnpm install && pnpm build and consume the ESM output in dist/ — the import below is the package’s entry point.

Once, early in your page or app bootstrap:

import { Environment, FortressFlag } from "@fortressflag/sdk-web";
FortressFlag.start({
sdkKey: "ffc_prod_…", // from your project's SDK keys screen
environment: Environment.PRODUCTION,
});

start returns immediately; cached values from previous visits are available right away, and fresh values arrive in the background. The key is a client key — it’s visible in your page source by design.

if (FortressFlag.isEnabled("new-checkout", false)) {
// render the new checkout
}

stringValue and numberValue read multivariate flags the same way, and FortressFlag.onChange tells you when values move so you can re-render.

That’s it — your flag is live. Toggle it in the dashboard and open the page again (or wait out a poll) to watch it follow.

No call in this API throws, and no promise from it rejects. Every read resolves through the cascade: the freshest fetched value, then the last value this browser recorded, then your default, then false. A FortressFlag outage, a dead network, an ad blocker, a revoked key — all of them resolve to a flag value, none of them reach your code as an error.

(That ad-blocker case is real: some privacy extensions block flag requests. Cached values keep serving, and a browser that never fetched serves your defaults — “flags don’t update with uBlock on” is the cascade working, not a bug.)

  • The device identity lives in localStorage, scoped to your origin. It’s random-minted and pseudonymous — and readable by your page’s own JavaScript, the same class of value as the SDK key beside it.
  • Private windows mint throwaway identities. Each private session counts as a device while it lasts; a user clearing site data is a new device too. And one person on your website, iOS app, and Android app is up to three devices — there’s no cross-platform linkage, by design.
  • Your test suites are free. Browsers driven by Playwright, Selenium, Puppeteer, or Cypress declare themselves, and the SDK mints a sim_ identity there: served flags, never billed.
  • Version tags don’t exist on web. The SDK sends platform and sdkVersion automatically, but there’s no reliable appVersion or osVersion for a page — a targeting rule on those simply never matches a browser.