This product is not supported for your selected Datadog site. ().
Overview
Use DatadogProvider for most browser applications. It manages configuration fetching, context updates, and built-in telemetry. Follow JavaScript Feature Flags for that setup.
DatadogCoreProvider is an advanced, OpenFeature-compatible provider that evaluates configurations supplied by your application. It does not fetch or poll configuration, install tracking hooks, or send telemetry. With rules-based configuration, it evaluates targeting rules locally when the OpenFeature context changes, without fetching new assignments.
When to use this approach
Choose DatadogCoreProvider when your application needs one or more of these capabilities:
Evaluate targeting rules for changing contexts without a configuration request for each context change.
Supply configuration through an application-controlled delivery path, such as a server-rendered bootstrap payload.
Control configuration refreshes and compose only the tracking integrations the application needs.
Your application owns configuration availability, freshness, and the tracking life cycle.
Prerequisites
Install @datadog/openfeature-browser 2.0.0 or later, @openfeature/web-sdk, and @openfeature/core, following the JavaScript installation instructions. The examples use npm package imports.
To fetch rules from Datadog, provide a client token, environment name, and Datadog site.
Enabling client rules delivery for your organization requires Feature Flag Environment Config Write permission. This permission is not needed to use the SDK if the setting is already enabled. See Permissions and Access Control.
Browser Feature Flags are not supported for the selected Datadog site ().
Configuration delivered to a browser is inspectable, including any targeting rules and values it contains. Keep sensitive configuration and authorization decisions on the server. Client-side feature flags are not an access-control mechanism.
Getting started
For browser applications that change evaluation context repeatedly during a session, use fetchRulesConfiguration() with DatadogCoreProvider. Load the rules once, then reuse the provider and configuration for subsequent evaluations and context changes.
Feature Flags billing counts Monthly Flag Configuration Requests (MFCR), not local evaluations. The initial rules fetch and later refreshes count toward MFCR; local context changes do not.
Enable client rules delivery
Before fetching rules, enable client rules delivery for your organization. This setting is disabled by default.
Enable Allow local rule evaluation in client SDKs.
Click Save.
This setting is separate from the per-flag Client distribution channel. The standard precomputed DatadogProvider setup does not require it.
Fetch rules and initialize
Import DatadogCoreProvider and fetchRulesConfiguration from @datadog/openfeature-browser/rules-based. Fetch the rules and validate the result before supplying it to the provider:
import{DatadogCoreProvider,fetchRulesConfiguration,}from'@datadog/openfeature-browser/rules-based';import{OpenFeature}from'@openfeature/web-sdk';constconfigurationOptions={clientToken:'<CLIENT_TOKEN>',site:'',env:'<ENV_NAME>',};asyncfunctionloadRulesConfiguration(){constconfiguration=awaitfetchRulesConfiguration(configurationOptions);if(!configuration.rules){thrownewError(configuration.rulesError??'Expected a rules-based configuration');}returnconfiguration;}constconfiguration=awaitloadRulesConfiguration();constprovider=newDatadogCoreProvider();provider.setConfiguration(configuration);constdomain='browser-flags';awaitOpenFeature.setProviderAndWait(domain,provider,{targetingKey:'user-123',plan:'free',});constclient=OpenFeature.getClient(domain);constenabled=client.getBooleanValue('checkout_new',false);
The fetch helper makes the configuration request. Registering the provider and evaluating the flag do not fetch configuration. The helper also accepts a fetch implementation and an abort signal for application-controlled transport.
Catch initialization errors in your application’s startup flow and decide whether to retry or continue with default behavior. Do not assume the provider is ready if setProviderAndWait() rejects.
The rules configuration remains in memory and is evaluated against the new context. Do not call loadRulesConfiguration() again for each context change. No configuration request is made. Optional tracking hooks can still send telemetry for evaluations.
Use flat context attributes and supply the attributes needed for targeting explicitly. DatadogCoreProvider does not automatically copy user attributes from RUM.
Refresh configuration
The provider does not poll for flag changes. Choose when the application refreshes configuration, then replace it before subsequent evaluations:
try{constnextConfiguration=awaitloadRulesConfiguration();provider.setConfiguration(nextConfiguration);}catch(error){console.warn('Could not refresh flag configuration; keeping the previous configuration.',error);}
If fetching or parsing fails, the provider continues using the previous configuration. The example logs the error; add retries according to your application’s freshness requirements. Changes made in Datadog do not reach this provider until the application supplies updated configuration.
Optional: supply portable configuration
Instead of fetching rules in the browser, your application can deliver a serialized rules configuration. Create this string by calling configurationToString(configuration) on a rules configuration that you already fetched. Import this helper from @datadog/openfeature-browser/rules-based.
Deliver the resulting string to the browser through your application, for example, in a server-rendered bootstrap payload. Replace <SERIALIZED_RULES_CONFIGURATION> below with that string, and use this code instead of the loadRulesConfiguration() call in the initialization example:
import{configurationFromString}from'@datadog/openfeature-browser/rules-based';constconfiguration=configurationFromString('<SERIALIZED_RULES_CONFIGURATION>');if(!configuration.rules){thrownewError(configuration.rulesError??'Expected a rules-based configuration');}
The serialized string is not the raw binary response from the rules endpoint. Use the framework’s safe serialization mechanism when embedding configuration in HTML. Parsing and supplying the string do not make a configuration request.
Precomputed configurations
Precomputed configuration contains assignments for a specific context, not rules that can be reevaluated for different contexts. If you supply it to DatadogCoreProvider, pass the context returned by getPrecomputedContext(configuration) to setProviderAndWait(). A mismatched context causes an invalid-context error; the provider does not fetch replacement assignments.
Add optional tracking hooks
The provider performs evaluations without tracking by default. Add only the integrations the application needs:
Factory
Behavior
createDatadogExposureLoggingHook(trackingOptions)
Deduplicates and batches eligible exposure events.
Adds flag evaluations to an existing global DD_RUM instance. It does not initialize RUM or populate the evaluation context.
Use composeDatadogTrackingHooks() to initialize and shut down the selected integrations together. Register its hooks on the client from the initialization example before evaluations that need tracking:
These hooks run only for evaluations made through this client instance. Continue using the same client for tracked evaluations. Omit an integration’s import and factory call to exclude it. RUM tracking requires Browser RUM to be available as DD_RUM and can increase RUM-billed event counts.
Exposure and evaluation hooks do not collect events until initialize() completes. Exposure events are batched and deduplicated, so a repeated evaluation may not create another exposure request.
When tracking is no longer needed, unregister the hooks and shut down their resources:
client.clearHooks();awaittracking.shutdown();
clearHooks() removes all client-level hooks from this client; this example assumes the client is dedicated to this tracking setup. It does not remove global or provider hooks. shutdown() requests a final flush and stops tracking timers and subscriptions; returning does not guarantee that every network request has completed. Clearing hooks or removing the core provider alone does not shut down manually created tracking resources.
Further reading
Additional helpful documentation, links, and articles: