-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[codex] Fix Feature Flags documentation guidance #36573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
1195da3
98374a8
c5022d8
a56dfd9
9fc00e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
@@ -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 | ||
|
|
||
|
|
@@ -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") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Context from Codex: The Android SDK exposes |
||
| .build() | ||
| .asOpenFeatureProvider() | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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" >}}', | ||
|
|
@@ -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 | ||
|
|
@@ -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 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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( | ||
|
|
@@ -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( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Context from Codex: The page's client variable is |
||
| key: "paywall.layout", | ||
| defaultValue: "control" | ||
| ) | ||
|
|
@@ -387,12 +389,15 @@ Flags.enable(with: config) | |
| `customExposureEndpoint` | ||
| : Configures a custom server URL for sending flags exposure data. | ||
|
|
||
| `customEvaluationEndpoint` | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Context from Codex: The iOS |
||
| : 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. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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]. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Context from Codex: The browser provider validates |
||
|
|
||
| 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" >}}', | ||
|
|
@@ -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', | ||
|
|
@@ -199,6 +204,21 @@ await OpenFeature.setContext({ | |
| }); | ||
| {{< /code-block >}} | ||
|
|
||
| ## Configure browser provider options | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
|
|
@@ -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 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Context from Codex: The React page imports |
||
| {{< /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" >}}', | ||
|
|
@@ -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" >}} | ||
|
|
@@ -178,7 +183,6 @@ For example: | |
| import { useBooleanFlag } from '@openfeature/react-sdk'; | ||
| import { Suspense } from 'react'; | ||
|
|
||
| import | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Context from Codex: Removing this stray |
||
| 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
|
||
|
|
@@ -293,6 +297,21 @@ await OpenFeature.setContext({ | |
| }); | ||
| {{< /code-block >}} | ||
|
|
||
| ## Configure browser provider options | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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: | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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.