Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion content/en/feature_flags/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,29 @@ further_reading:

## Overview

Feature flags enable you to toggle features on and off, conduct A/B/n testing, gradually roll out new functionality, and personalize user experiences—all without the need for extensive code deployments. With feature flags, you can empower your team to make dynamic changes, iterate rapidly, and deliver enhanced user experiences.
Datadog Feature Flags is Datadog's flag management product. You create flags in Datadog, deliver flag configuration to Datadog SDKs, and evaluate variants in your application through Datadog or OpenFeature APIs.
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: This establishes the distinction the old hub was missing: Datadog Feature Flags is the flag-management product, while RUM Feature Flag Tracking is the observability path for third-party providers. Without that distinction, browser telemetry settings later in the docs are easy to misread.


Feature flags enable you to toggle features on and off, conduct A/B/n testing, gradually roll out new functionality, and personalize user experiences without the need for extensive code deployments. With feature flags, you can empower your team to make dynamic changes, iterate rapidly, and deliver enhanced user experiences.

If your flags are managed by LaunchDarkly, Split, ConfigCat, or another provider and you only want Datadog to record evaluated variants in RUM, see [RUM Feature Flag Tracking](/real_user_monitoring/feature_flag_tracking/) instead.

Use a client-side SDK when the flag must be evaluated in a browser, mobile app, or game client. Use a server-side SDK when the decision should happen in a backend service and the flag configuration can be delivered through the Datadog Agent and Remote Configuration.

### Credentials at a glance

| Credential | Used by | Where it goes | Sensitive? |
| --- | --- | --- | --- |
| Client token | Browser, mobile, and game SDKs | Client application configuration | Public-shipping token |
| Application ID | Browser and RUM-backed client SDKs | Client application configuration | Public-shipping identifier |
| API key | Datadog Agent for server-side Remote Configuration | Agent configuration only | Secret |

Do not put API keys in browser, mobile, or game applications.

### Evaluation context and telemetry

Evaluation context attributes are the flat string, number, and Boolean values that Datadog uses for targeting rules and rollout bucketing. Set a stable `targetingKey`, such as a user ID, session ID, or device ID, so percentage rollouts are consistent.

Feature Flags telemetry includes exposure events, flag evaluation metrics, and optional RUM correlation depending on the SDK and configuration. For third-party feature flag providers, use [RUM Feature Flag Tracking](/real_user_monitoring/feature_flag_tracking/) to send evaluated variants to RUM without migrating flag management to Datadog.

## Further reading

Expand Down
5 changes: 4 additions & 1 deletion content/en/feature_flags/client/android.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ OpenFeatureAPI.setProviderAndWait(provider)

Define who or what the flag evaluation applies to using an `ImmutableContext`. The evaluation context includes user or session information used to determine which flag variations should be returned. Set this before evaluating flags to help ensure proper targeting.

<div class="alert alert-warning">Datadog Feature Flags requires evaluation-context attributes to be flat primitive values: strings, numbers, and Booleans. Do not pass nested objects or arrays; they are not supported and can cause exposure data to be dropped.</div>

{{< code-block lang="kotlin" >}}
import dev.openfeature.kotlin.sdk.ImmutableContext
import dev.openfeature.kotlin.sdk.Value
Expand All @@ -143,7 +145,7 @@ OpenFeatureAPI.setEvaluationContext(
)
{{< /code-block >}}

<div class="alert alert-info">All attribute values must use a <code>Value.String()</code> wrapper. The targeting key should be consistent for the same user to help ensure consistent flag evaluation across sessions. For anonymous users, use a persistent UUID stored, for example, in <code>SharedPreferences</code>.</div>
<div class="alert alert-info">OpenFeature attributes must use flat <code>Value</code> primitives such as <code>Value.String()</code>, <code>Value.Integer()</code>, <code>Value.Double()</code>, or <code>Value.Boolean()</code>. The targeting key should be consistent for the same user to help ensure consistent flag evaluation across sessions. For anonymous users, use a persistent UUID stored, for example, in <code>SharedPreferences</code>.</div>

## Evaluate flags

Expand Down Expand Up @@ -288,6 +290,7 @@ You can configure individual providers with custom endpoints before creating the
val provider = FlagsClient.Builder()
.useCustomFlagEndpoint("https://your-proxy.example.com/flags")
.useCustomExposureEndpoint("https://your-proxy.example.com/exposure")
.useCustomEvaluationEndpoint("https://your-proxy.example.com/evaluations")
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: The Android SDK exposes useCustomEvaluationEndpoint alongside custom flag and exposure endpoints. Adding it keeps the advanced proxy example complete for all three Feature Flags traffic paths.

.build()
.asOpenFeatureProvider()

Expand Down
66 changes: 64 additions & 2 deletions content/en/feature_flags/client/angular.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@ pnpm add @datadog/openfeature-browser @openfeature/angular-sdk @openfeature/web-

## Initialize the provider

Create a `DatadogProvider` instance with your Datadog credentials. To create a client token, see [Client tokens][2].
Create a `DatadogProvider` instance with your Datadog credentials. `applicationId`, `clientToken`, `site`, and `env` are required. To create a client token, see [Client tokens][2].

Supported browser Feature Flags sites are `datadoghq.com`, `us3.datadoghq.com`, `us5.datadoghq.com`, `ap1.datadoghq.com`, `ap2.datadoghq.com`, and `datadoghq.eu`. Browser Feature Flags are not supported on GovCloud sites.

```typescript
import { DatadogProvider } from '@datadog/openfeature-browser';

const provider = new DatadogProvider({
// Required client-side Datadog credentials
applicationId: '<APPLICATION_ID>',
clientToken: '<CLIENT_TOKEN>',
site: '{{< region-param key="dd_site" code="true" >}}',
Expand All @@ -71,6 +74,8 @@ Import the `OpenFeatureModule` in your Angular module and configure it using the

Define who or what the flag evaluation applies to using an evaluation context. The evaluation context includes user or session information used to determine which flag variations should be returned. Reference these attributes in your targeting rules to control who sees each variant.

<div class="alert alert-warning">Datadog Feature Flags requires evaluation-context attributes to be flat primitive values: strings, numbers, and Booleans. Do not pass nested objects or arrays; they are not supported and can cause exposure data to be dropped.</div>

<div class="alert alert-info">The <code>targetingKey</code> is used as the randomization subject for percentage-based targeting. When a flag targets a percentage of subjects (for example, 50%), the <code>targetingKey</code> determines which "bucket" a user falls into. Users with the same <code>targetingKey</code> always receive the same variant for a given flag.</div>

### Using a static object
Expand Down Expand Up @@ -489,10 +494,67 @@ export class MyComponent {
}
{{< /code-block >}}

## Configure browser provider options

The Angular provider uses the Datadog browser provider, which also supports these optional settings:

| Option | Default | Use |
| --- | --- | --- |
| `enableExposureLogging` | `true` | Send exposure events to the exposures intake. |
| `enableFlagEvaluationTracking` | `true` | Send aggregated evaluation telemetry. |
| `enableRumFeatureFlagTracking` | `true` | Add flag evaluations to RUM events. This is the setting that can affect RUM usage. |
| `flagEvaluationTrackingInterval` | `10000` ms | Flush interval for evaluation telemetry. |
| `initialFlagsConfiguration` | `{}` | Bootstrap with precomputed flags. |
| `flaggingProxy` | unset | Fetch flags through a proxy instead of `site`. |
| `customHeaders` | unset | Add headers to flag-fetch requests. |
| `overwriteRequestHeaders` | `false` | Replace default request headers with `customHeaders`. |

## Testing
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: The client hub says platform pages have concrete testing examples, but Angular did not. This adds the same in-memory-provider pattern shown on the JS/React pages so Angular tests can stay hermetic and offline.


You can test against a dedicated Datadog test environment with the real `DatadogProvider`, or swap it for OpenFeature's `TypedInMemoryProvider` to control flag values directly in test code. This section shows the in-memory approach, which keeps tests hermetic and offline. `TypedInMemoryProvider` is exported from `@openfeature/web-sdk`, which is already installed for Angular Feature Flags.

{{< code-block lang="typescript" >}}
import { TestBed } from '@angular/core/testing';
import { firstValueFrom } from 'rxjs';
import { FeatureFlagService, OpenFeatureModule } from '@openfeature/angular-sdk';
import { TypedInMemoryProvider } from '@openfeature/web-sdk';

const flags = {
new_checkout_button: {
variants: { on: true, off: false },
defaultVariant: 'on',
disabled: false,
},
};

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
OpenFeatureModule.forRoot({
provider: new TypedInMemoryProvider(flags),
context: { targetingKey: 'test-user' },
}),
],
}).compileComponents();
});

afterEach(() => {
TestBed.resetTestingModule();
});

it('uses in-memory flag values', async () => {
const flagService = TestBed.inject(FeatureFlagService);
const details = await firstValueFrom(flagService.getBooleanDetails('new_checkout_button', false));

expect(details.value).toBe(true);
});
{{< /code-block >}}

The Web SDK flag shape requires `variants`, `defaultVariant`, and `disabled`. Register the in-memory provider before injecting services or rendering components that read flags.

## Further reading

{{< partial name="whats-next/whats-next.html" >}}

[1]: https://openfeature.dev/docs/reference/sdks/client/web/angular/
[2]: /account_management/api-app-keys/#client-tokens

9 changes: 7 additions & 2 deletions content/en/feature_flags/client/ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ let flagsClient = FlagsClient.shared(named: "checkout")

Define who or what the flag evaluation applies to using a `FlagsEvaluationContext`. The evaluation context includes user or session information used to determine which flag variations should be returned. Call this method before evaluating flags to ensure proper targeting.

<div class="alert alert-warning">Datadog Feature Flags requires evaluation-context attributes to be flat primitive values: strings, numbers, and Booleans. Do not pass nested objects or arrays; they are not supported and can cause exposure data to be dropped.</div>

{{< code-block lang="swift" >}}
flagsClient.setEvaluationContext(
FlagsEvaluationContext(
Expand Down Expand Up @@ -240,7 +242,7 @@ When you need more than just the flag value, use the `get<Type>Details` APIs. Th
For example:

{{< code-block lang="swift" >}}
let details = flags.getStringDetails(
let details = flagsClient.getStringDetails(
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: The page's client variable is flagsClient, and the iOS API exposes getStringDetails on that client. The old flags.getStringDetails snippet would not compile as written.

key: "paywall.layout",
defaultValue: "control"
)
Expand Down Expand Up @@ -387,12 +389,15 @@ Flags.enable(with: config)
`customExposureEndpoint`
: Configures a custom server URL for sending flags exposure data.

`customEvaluationEndpoint`
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: The iOS Flags.Configuration exposes customEvaluationEndpoint, but the docs only listed flag and exposure endpoints. Adding it brings iOS in line with the SDK and the Unity page.

: Configures a custom server URL for sending flag evaluation telemetry.

`customFlagsHeaders`
: Sets additional HTTP headers to attach to requests made to `customFlagsEndpoint`. It can be useful for authentication or routing when using your own flags service.

## Testing

The examples above use Datadog's `FlagsClient` API directly. If you prefer to drive feature flags through the [OpenFeature](https://openfeature.dev/) standard API, Datadog ships an OpenFeature bridge for iOS at [dd-openfeature-provider-swift](https://github.com/DataDog/dd-openfeature-provider-swift). Use the bridge's `DatadogProvider` in production, and for code-controlled flag values in tests, substitute an in-memory provider.
The examples above use Datadog's `FlagsClient` API directly. Use `FlagsClient` for production workloads. If you are prototyping against the [OpenFeature](https://openfeature.dev/) bridge or writing tests around the OpenFeature API, substitute an in-memory provider for code-controlled flag values.
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: The iOS OpenFeature bridge README says the bridge is still in development and not ready for production. This removes the page-level contradiction that previously told users to use the bridge's provider in production.


You can test against a dedicated Datadog test environment with the real `DatadogProvider`, or swap it for an in-memory `FeatureProvider` to control flag values directly in test code. This section shows the in-memory approach, which keeps tests hermetic and offline. The OpenFeature Swift SDK does not ship an `InMemoryProvider`, so tests use a small custom `FeatureProvider` instead.

Expand Down
23 changes: 21 additions & 2 deletions content/en/feature_flags/client/javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,16 @@ pnpm add @datadog/openfeature-browser @openfeature/web-sdk @openfeature/core

## Initialize the provider

Create a `DatadogProvider` instance with your Datadog credentials. To create a client token, see [Client tokens][2].
Create a `DatadogProvider` instance with your Datadog credentials. `applicationId`, `clientToken`, `site`, and `env` are required. To create a client token, see [Client tokens][2].
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: The browser provider validates applicationId during initialization and returns early if it is missing. Marking the required fields here aligns the docs with runtime behavior instead of just showing the field in examples.


Supported browser Feature Flags sites are `datadoghq.com`, `us3.datadoghq.com`, `us5.datadoghq.com`, `ap1.datadoghq.com`, `ap2.datadoghq.com`, and `datadoghq.eu`. Browser Feature Flags are not supported on GovCloud sites.

```javascript
import { DatadogProvider } from '@datadog/openfeature-browser';
import { OpenFeature } from '@openfeature/web-sdk';

const provider = new DatadogProvider({
// Required client-side Datadog credentials
applicationId: '<APPLICATION_ID>',
clientToken: '<CLIENT_TOKEN>',
site: '{{< region-param key="dd_site" code="true" >}}',
Expand All @@ -63,6 +66,8 @@ const provider = new DatadogProvider({

Define who or what the flag evaluation applies to using an evaluation context. The evaluation context includes user or session information used to determine which flag variations should be returned. Reference these attributes in your targeting rules to control who sees each variant.

<div class="alert alert-warning">Datadog Feature Flags requires evaluation-context attributes to be flat primitive values: strings, numbers, and Booleans. Do not pass nested objects or arrays; they are not supported and can cause exposure data to be dropped.</div>

{{< code-block lang="javascript" >}}
const evaluationContext = {
targetingKey: 'user-123',
Expand Down Expand Up @@ -199,6 +204,21 @@ await OpenFeature.setContext({
});
{{< /code-block >}}

## Configure browser provider options
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: These browser-provider options exist in the public SDK but were absent from the JS page. Documenting them here makes the JS page match the behavior customers can configure, especially the three separate telemetry streams.


The web provider also supports these optional settings:

| Option | Default | Use |
| --- | --- | --- |
| `enableExposureLogging` | `true` | Send exposure events to the exposures intake. |
| `enableFlagEvaluationTracking` | `true` | Send aggregated evaluation telemetry. |
| `enableRumFeatureFlagTracking` | `true` | Add flag evaluations to RUM events. This is the setting that can affect RUM usage. |
| `flagEvaluationTrackingInterval` | `10000` ms | Flush interval for evaluation telemetry. |
| `initialFlagsConfiguration` | `{}` | Bootstrap with precomputed flags. |
| `flaggingProxy` | unset | Fetch flags through a proxy instead of `site`. |
| `customHeaders` | unset | Add headers to flag-fetch requests. |
| `overwriteRequestHeaders` | `false` | Replace default request headers with `customHeaders`. |

## Testing

You can test against a dedicated Datadog test environment with the real `DatadogProvider`, or swap it for OpenFeature's `InMemoryProvider` to control flag values directly in test code. This section shows the in-memory approach, which keeps tests hermetic and offline. `InMemoryProvider` is exported directly from `@openfeature/web-sdk`, so no additional dependency is required.
Expand Down Expand Up @@ -249,4 +269,3 @@ The Web SDK flag shape requires `variants`, `defaultVariant`, and `disabled`. Om

[1]: https://openfeature.dev/
[2]: /account_management/api-app-keys/#client-tokens

29 changes: 24 additions & 5 deletions content/en/feature_flags/client/react.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,34 @@ Install the Datadog OpenFeature provider and the OpenFeature React SDK using you
{{< tabs >}}
{{% tab "npm" %}}
{{< code-block lang="bash" >}}
npm install @datadog/openfeature-browser @openfeature/react-sdk @openfeature/core
npm install @datadog/openfeature-browser @openfeature/react-sdk @openfeature/web-sdk @openfeature/core
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: The React page imports TypedInMemoryProvider from @openfeature/web-sdk later, and @datadog/openfeature-browser also declares the Web SDK as a peer dependency. Adding it to the install command prevents copy-paste setup failures.

{{< /code-block >}}
{{% /tab %}}

{{% tab "yarn" %}}
{{< code-block lang="bash" >}}
yarn add @datadog/openfeature-browser @openfeature/react-sdk @openfeature/core
yarn add @datadog/openfeature-browser @openfeature/react-sdk @openfeature/web-sdk @openfeature/core
{{< /code-block >}}
{{% /tab %}}

{{% tab "pnpm" %}}
{{< code-block lang="bash" >}}
pnpm add @datadog/openfeature-browser @openfeature/react-sdk @openfeature/core
pnpm add @datadog/openfeature-browser @openfeature/react-sdk @openfeature/web-sdk @openfeature/core
{{< /code-block >}}
{{% /tab %}}
{{< /tabs >}}

## Initialize the provider

Create a `DatadogProvider` instance and register it with OpenFeature. Do this as early as possible in your application, before rendering your React components. To create a client token, see [Client tokens][2].
Create a `DatadogProvider` instance and register it with OpenFeature. Do this as early as possible in your application, before rendering your React components. `applicationId`, `clientToken`, `site`, and `env` are required. To create a client token, see [Client tokens][2].

Supported browser Feature Flags sites are `datadoghq.com`, `us3.datadoghq.com`, `us5.datadoghq.com`, `ap1.datadoghq.com`, `ap2.datadoghq.com`, and `datadoghq.eu`. Browser Feature Flags are not supported on GovCloud sites.

```javascript
import { DatadogProvider } from '@datadog/openfeature-browser';

const provider = new DatadogProvider({
// Required client-side Datadog credentials
applicationId: '<APPLICATION_ID>',
clientToken: '<CLIENT_TOKEN>',
site: '{{< region-param key="dd_site" code="true" >}}',
Expand All @@ -62,6 +65,8 @@ const provider = new DatadogProvider({

Define who or what the flag evaluation applies to using an evaluation context. The evaluation context includes user or session information used to determine which flag variations should be returned. Reference these attributes in your targeting rules to control who sees each variant.

<div class="alert alert-warning">Datadog Feature Flags requires evaluation-context attributes to be flat primitive values: strings, numbers, and Booleans. Do not pass nested objects or arrays; they are not supported and can cause exposure data to be dropped.</div>

Set the provider along with the evaluation context:

{{< code-block lang="javascript" >}}
Expand Down Expand Up @@ -178,7 +183,6 @@ For example:
import { useBooleanFlag } from '@openfeature/react-sdk';
import { Suspense } from 'react';

import
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: Removing this stray import line fixes the Suspense example so it is valid JSX rather than a copy-paste syntax error.

function Content() {
// Display a loading message if the component uses feature flags and the provider is not ready
return (
Comment on lines 183 to 188
Expand Down Expand Up @@ -293,6 +297,21 @@ await OpenFeature.setContext({
});
{{< /code-block >}}

## Configure browser provider options
Copy link
Copy Markdown
Contributor Author

@aarsilv aarsilv May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Context from Codex: React uses the same Datadog browser provider underneath, so it should document the same provider-level options as the JavaScript page. This also gives React users the correct RUM-vs-exposure-vs-evaluation controls.


The React provider uses the Datadog browser provider, which also supports these optional settings:

| Option | Default | Use |
| --- | --- | --- |
| `enableExposureLogging` | `true` | Send exposure events to the exposures intake. |
| `enableFlagEvaluationTracking` | `true` | Send aggregated evaluation telemetry. |
| `enableRumFeatureFlagTracking` | `true` | Add flag evaluations to RUM events. This is the setting that can affect RUM usage. |
| `flagEvaluationTrackingInterval` | `10000` ms | Flush interval for evaluation telemetry. |
| `initialFlagsConfiguration` | `{}` | Bootstrap with precomputed flags. |
| `flaggingProxy` | unset | Fetch flags through a proxy instead of `site`. |
| `customHeaders` | unset | Add headers to flag-fetch requests. |
| `overwriteRequestHeaders` | `false` | Replace default request headers with `customHeaders`. |

## Testing

You can test against a dedicated Datadog test environment with the real `DatadogProvider`, or swap it for OpenFeature's `TypedInMemoryProvider` to control flag values directly in test code. This section shows the in-memory approach, which keeps tests hermetic and offline. `TypedInMemoryProvider` is exported from `@openfeature/web-sdk`; install it as a development dependency and register it before rendering components under test:
Expand Down
Loading
Loading