Skip to main content

Register the provider

Call setProviderAndWait once at application startup. It awaits the provider’s initialize, which performs the first /v1/sync call and opens the event stream before the promise resolves, so the first evaluation reads real values rather than defaults.
setProviderAndWait rejects if the service cannot be read. A provider that cannot read the service is not ready, and reporting otherwise would serve every caller’s default as though it were an answer. Which error arrives says whether it is worth trying again. A failure only a change to what you passed in can fix - a rejected API key, a base URL naming no service, a configuration value the client will not accept - arrives as OpenFeature’s own ProviderFatalError, carrying error code PROVIDER_FATAL. The client goes to FATAL, and the SDK stops calling this provider’s resolvers, so every evaluation returns your default at once rather than through a client that will never be there. The underlying Nexus error is on cause. Anything else - a timed-out request, an unreachable network, a server error, an overdue invoice - arrives as a NexusInitError with the reason on cause. The client goes to ERROR, and registering the provider again can clear it.
instanceof answers from a brand rather than from the prototype chain, so it holds for an error raised by any copy of these classes: this package ships an ES module and a CommonJS build, and the Angular, React and Vue SDKs carry copies of their own.

Evaluating flags

Use the *Details variants to see why a value was resolved:

Per-user targeting

Set an evaluation context once the user is known, and every boolean evaluation afterwards is answered for that user - AB tests, cohort rules and percentage rollouts apply.
A targeting-key change is asynchronous: resolveBooleanEvaluation is synchronous in the OpenFeature Web SDK, so the provider fetches when the context changes rather than during an evaluation. Await setContext.
Targeting covers when the provider fetches, what it sends, what each reason means, and how it behaves when the service is unreachable.

Reacting to live updates

The provider holds an event stream open. When a flag or config actually changes it re-syncs, re-asks the targeted answers, and emits ConfigurationChanged. A stream reconnect on its own does not emit it - nothing about the configuration moved.

Type resolution rules

Inside a resolved object or array, an integer beyond Number.MAX_SAFE_INTEGER is carried as its exact decimal string, at any depth - OpenFeature’s JsonValue has no numeric slot that holds it exactly, and the decimal string is the lossless one, so the resolved value survives JSON.stringify. Ordinary numbers are untouched; parse the string with BigInt(value) where the magnitude matters. The scalar getNumberValue answers TYPE_MISMATCH for the same value on purpose. Non-boolean resolutions are never targeted. String, number and object evaluations map to configuration values, and targeted evaluation is a flag concept - there is no such thing as a targeted config value.

Framework examples

Svelte, Solid, Lit, or plain DOM code

React (with @openfeature/react-sdk)

An application built on @westyx-nexus/sdk-angular, -react or -vue should use that SDK’s own OpenFeature bridge - Angular, React or Vue - which wraps the client it already has. This package creates and owns one.

Server-side rendering

The provider opens no event stream where the environment cannot hold one, so it is safe to construct during a server-side rendering pass. A connection opened there is never torn down by anything the framework calls, and it holds the request open.

When the stream never connects at all

A stream that fails from the start is a different problem from one that drops: the provider reaches READY, every evaluation is answered from the cache, and the values are correct once and then never change. It looks like a working integration. The client says so once, after it gives up on its first connection:
It goes to the logger you configured, or to console.warn if you configured none, so the message reaches the consumer least likely to be looking for it. A connection lost after one succeeded is not reported this way - the stream observer covers that. The usual causes in a browser are CORS-shaped. The stream request carries X-Nexus-API-Key, which is not a CORS-safelisted header, so the browser preflights it: the endpoint has to allow this origin and name that header in Access-Control-Allow-Headers. A blocked preflight is indistinguishable from an unreachable server to the SDK, which is why the message names both.

Stopping the provider

This calls onClose(), which releases the event stream, every timer, every listener and the identity the provider was holding.

Notes

  • Public key only. Use a wxp_... browser key. Secret backend keys (wxs_...) are not accepted.
  • No secrets. Secret values are never served to a browser key. Only feature flags and configuration are available.