Repository navigation
Conversation
Add a Load a subset of flags section to the JavaScript client page and a proxy note for the DD-Flag-Selection-Ignored header. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Preview links (active after the
|
Nest the Load a subset of flags section under Initialize the provider, since flagSelection is set when the provider is created. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Add the OpenFeature.getClient() call to the Evaluate flags outside the selection example, since client is otherwise first defined in the later Get a client section. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Set the minimum @datadog/openfeature-browser version to 2.2.0 and note that Datadog returns the full configuration without DD-Flag-Selection-Ignored when flag selection is not enabled for the organization. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Flag selection is rolling out globally, so the no-header case no longer refers to per-organization enablement. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Remove the no-header case and state that flags outside the selection are not loaded. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Lead with the risk that team tags change with ownership, and render it as a WARNING callout. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
List each limit on its own line so the 31-value limit is not read as a combined total. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Matches MAX_RULES_URL_BYTES and the too_many_values console error in @datadog/openfeature-browser 2.2.0. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
State that too_many_values also covers selections too long for one request, document that empty selections load the full configuration silently, and scope the Access-Control-Expose-Headers requirement to cross-origin proxies. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Add the two console error templates the browser SDK logs when it does not send a flag selection or when Datadog ignores it. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
State in one sentence that flagSelection does not filter configuration supplied with initialFlagsConfiguration. Environment: Datadog workspace Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Created DOCS-16170 for review |
| }); | ||
| {{< /code-block >}} | ||
|
|
||
| If you use [`flagSelection`][3] to load a subset of flags, return the `DD-Flag-Selection-Ignored` response header to the browser unchanged. If your proxy is on a different origin from your application, also list the header in the `Access-Control-Expose-Headers` response header. Datadog sets this header when it ignores a selection and returns the full flag configuration. If the browser cannot read the header, the full configuration still loads, but the SDK cannot report that the selection was ignored. |
There was a problem hiding this comment.
🤖 Comment from Claude working with Aaron Silverman (aarsilv):
[P1] Please change this tab's examples to DatadogProvider. This new paragraph and the new link from the browser SDK page send readers to these examples.
Line 177 says "Pass configuration options to DatadogBrowserFlagging.init()." All three code samples in this tab call DatadogBrowserFlagging.init(), and the first one imports it from @datadog/browser-flagging. That package is not on npm: npm view @datadog/browser-flagging returns 404. The published SDK is @datadog/openfeature-browser, which exports DatadogProvider. The option names in the samples are correct: flaggingProxy, customHeaders, and proxy are all DatadogProvider options. The samples also omit applicationId and env, which the browser SDK page lists as required for live configuration.
Suggested text for line 177: "Pass these options to DatadogProvider from @datadog/openfeature-browser."
Suggested first sample:
import { DatadogProvider } from '@datadog/openfeature-browser';
const provider = new DatadogProvider({
applicationId: '<APPLICATION_ID>',
clientToken: '<CLIENT_TOKEN>',
site: 'datadoghq.com',
env: '<ENV_NAME>',
flaggingProxy: 'https://proxy.example.com/precompute-assignments',
});The other two samples use the same constructor with the same four required options, and keep their extra option (customHeaders or proxy).
This problem is older than this PR. proxy_server_setup.md uses DatadogBrowserFlagging too and can get the same fix later.
|
|
||
| If the flag selection is malformed or exceeds a limit, the SDK does not send it in the flag configuration request, logs an error to the browser console, and loads the full flag configuration. | ||
|
|
||
| Datadog can also ignore a selection and return the full flag configuration. In that case, the response includes a `DD-Flag-Selection-Ignored` header with one of the following reasons, and the SDK logs an error to the browser console: |
There was a problem hiding this comment.
🤖 Comment from Claude working with Aaron Silverman (aarsilv):
[P2] Please connect this paragraph to line 130. Line 130 says that the SDK does not send a selection that fails these limits. This paragraph then lists the same limits as reasons for Datadog to ignore a selection. So a reader can expect this header for a selection that the SDK did not send.
With the SDK, this header reports problems that the SDK does not check. One example is a selection that is too long to send in one request (too_many_values). Another example is tags that fail to load (tag_load_failed). In my test, a selection with 31 tags and 31 key patterns of 200 bytes each passed the SDK checks. Datadog then ignored it with too_many_values, and the SDK logged "flagSelection was ignored by the server (too_many_values)".
Suggested text for this paragraph:
Because the SDK checks these limits first, selections that fail them never reach Datadog. Datadog can still ignore a selection that passes these checks, for example when the selection is too long to send in one request. In that case, Datadog returns the full flag configuration with a
DD-Flag-Selection-Ignoredheader that gives one of the following reasons, and the SDK logs an error to the browser console:
|
|
||
| - `tags` contains at most 31 values. | ||
| - `keyPatterns` contains at most 31 values. | ||
| - Each tag is at most 200 bytes (UTF-8). |
There was a problem hiding this comment.
🤖 Comment from Claude working with Aaron Silverman (aarsilv):
[P3] Consider one sentence that connects this limit to the tags on flags. Datadog lets you add a tag longer than 200 bytes to a flag, and a reader can then try to select it.
A selection with that tag fails the SDK check (invalid_tag). The SDK then drops the whole selection and requests the full flag configuration.
Suggested sentence after this list:
A selection cannot include a tag longer than 200 bytes, so keep the tags you add to flags for selection at 200 bytes or less.
|
|
||
| | Message | Cause | | ||
| | --- | --- | | ||
| | `Datadog Browser SDK: flagSelection was not sent (<REASON>: <LIMIT>). Loading the full flag configuration.` | The selection is malformed or exceeds a limit. | |
There was a problem hiding this comment.
🤖 Comment from Claude working with Aaron Silverman (aarsilv):
[P3] Consider <DETAIL> instead of <LIMIT> in this message. For malformed_selection, the text in that position is not a limit: "flagSelection must be an object with optional tags and keyPatterns string arrays". <DETAIL> fits every case.
|
|
||
| #### Rules-based configuration | ||
|
|
||
| `fetchRulesConfiguration()` from `@datadog/openfeature-browser/rules-based` accepts the same `flagSelection` option, with the same matching rules and limits. The request URL, including the encoded selection, must be at most 8,192 bytes. If it would be longer, the SDK does not send the selection, logs a `too_many_values` error to the browser console, and loads the full configuration. See [Browser Rules-Based Evaluation][4]. |
There was a problem hiding this comment.
🤖 Comment from Claude working with Aaron Silverman (aarsilv):
Heads up: cc @sameerank. Rules-based fetches send the selection in the URL query string. The precompute request sends it in the POST body instead. This matters when an application routes the rules fetch through its own proxy or a custom fetch:
- The proxy must keep the
selected_flag_tagsandselected_flag_key_patternsquery parameters, including repeated ones. - A cache in front of the rules fetch must include these parameters in its cache key. If it does not, two selections can share one cached response.
No change requested in this PR. The React Native rules fetch helper in DataDog/dd-sdk-reactnative#1508 requests the same endpoint, so the same points apply there if it adds selection support.
joepeeples
left a comment
There was a problem hiding this comment.
Thanks for this new content, @mark-caii! I flagged a few possible edits, and one overall structural suggestion: Consider moving Load a subset of flags under Configure browser provider options, as an H3. Where it sits now, it interrupts the basic setup flow with an optional, advanced feature.
Feel free to ping directly when ready for a quick re-review, thanks!
|
|
||
| ### Load a subset of flags | ||
|
|
||
| In `@datadog/openfeature-browser` 2.2.0 and later, use `flagSelection` to load only the flags your application needs instead of every flag in the environment. Selecting a subset reduces the size of the flag configuration the SDK downloads and caches, which helps when an environment contains flags for many applications. Pass `flagSelection` to the provider when you create it; the selection is fixed for the provider's lifetime, so to load a different set of flags, create a new provider. |
There was a problem hiding this comment.
| In `@datadog/openfeature-browser` 2.2.0 and later, use `flagSelection` to load only the flags your application needs instead of every flag in the environment. Selecting a subset reduces the size of the flag configuration the SDK downloads and caches, which helps when an environment contains flags for many applications. Pass `flagSelection` to the provider when you create it; the selection is fixed for the provider's lifetime, so to load a different set of flags, create a new provider. | |
| In `@datadog/openfeature-browser` 2.2.0 and later, use `flagSelection` to load only the flags your application needs instead of every flag in the environment. Loading a subset reduces the size of the flag configuration that the SDK downloads and caches, which helps when an environment contains flags for many applications. | |
| Pass `flagSelection` to the provider when you create it. The selection is fixed for the provider's lifetime. To load a different set of flags, create a new provider. |
| }); | ||
| ``` | ||
|
|
||
| <div class="alert alert-warning">Team tags can change when ownership changes, which could change the flags your application loads. Add tags to your flags specifically for selection, such as <code>app:checkout-web</code>, rather than selecting by team tags.</div> |
There was a problem hiding this comment.
| <div class="alert alert-warning">Team tags can change when ownership changes, which could change the flags your application loads. Add tags to your flags specifically for selection, such as <code>app:checkout-web</code>, rather than selecting by team tags.</div> | |
| <div class="alert alert-warning">Team tags can change when flag ownership changes, which changes the flags your application loads. Instead of selecting by team tags, add tags to your flags specifically for selection, such as <code>app:checkout-web</code>.</div> |
| | Message | Cause | | ||
| | --- | --- | | ||
| | `Datadog Browser SDK: flagSelection was not sent (<REASON>: <LIMIT>). Loading the full flag configuration.` | The selection is malformed or exceeds a limit. | | ||
| | `Datadog Browser SDK: flagSelection was ignored by the server (<REASON>). Loaded the full flag configuration.` | Datadog ignored the selection. See the reasons above. | |
There was a problem hiding this comment.
| | `Datadog Browser SDK: flagSelection was ignored by the server (<REASON>). Loaded the full flag configuration.` | Datadog ignored the selection. See the reasons above. | | |
| | `Datadog Browser SDK: flagSelection was ignored by the server (<REASON>). Loaded the full flag configuration.` | Datadog ignored the selection. See the reasons in the previous table. | |
|
|
||
| #### Initial configuration is not filtered | ||
|
|
||
| `flagSelection` does not filter configuration you supply with [`initialFlagsConfiguration`](#supply-initial-precomputed-fallback-data); the SDK uses it as provided. |
There was a problem hiding this comment.
| `flagSelection` does not filter configuration you supply with [`initialFlagsConfiguration`](#supply-initial-precomputed-fallback-data); the SDK uses it as provided. | |
| `flagSelection` does not filter configuration that you supply with `initialFlagsConfiguration`. The SDK uses that configuration as provided. For details, see the [Supply initial precomputed fallback data](#supply-initial-precomputed-fallback-data) section. |
| }); | ||
| {{< /code-block >}} | ||
|
|
||
| If you use [`flagSelection`][3] to load a subset of flags, return the `DD-Flag-Selection-Ignored` response header to the browser unchanged. If your proxy is on a different origin from your application, also list the header in the `Access-Control-Expose-Headers` response header. Datadog sets this header when it ignores a selection and returns the full flag configuration. If the browser cannot read the header, the full configuration still loads, but the SDK cannot report that the selection was ignored. |
There was a problem hiding this comment.
| If you use [`flagSelection`][3] to load a subset of flags, return the `DD-Flag-Selection-Ignored` response header to the browser unchanged. If your proxy is on a different origin from your application, also list the header in the `Access-Control-Expose-Headers` response header. Datadog sets this header when it ignores a selection and returns the full flag configuration. If the browser cannot read the header, the full configuration still loads, but the SDK cannot report that the selection was ignored. | |
| If you use [`flagSelection`][3] to load a subset of flags, your proxy must return the `DD-Flag-Selection-Ignored` response header to the browser unchanged. Datadog sets this header when it ignores a selection and returns the full flag configuration. If your proxy is on a different origin from your application, also list the header in the `Access-Control-Expose-Headers` response header. If the browser cannot read the header, the full configuration still loads, but the SDK cannot report that the selection was ignored. |
What does this PR do? What is the motivation?
Ticket: FFL-3457
Documents the
flagSelectionoption of the browser SDK (@datadog/openfeature-browser), which loads only the flags that match a set of tags or key patterns.feature_flags/client/javascript.md: addsflagSelectionto the provider options table and a Load a subset of flags section covering matching rules (exact, case-sensitive tags; whole-key globs where only*is special; tags OR key patterns), limits (31 values per list, 200 UTF-8 bytes per value), what happens when a selection is dropped by the SDK or ignored by Datadog (DD-Flag-Selection-Ignoredreasons),FLAG_NOT_FOUNDfor flags outside the selection,initialFlagsConfigurationnot being filtered, andfetchRulesConfiguration()support.feature_flags/guide/proxy_sdk_traffic.md: the Browser tab notes that a proxy must pass throughDD-Flag-Selection-Ignoredand expose it withAccess-Control-Expose-Headers.Merge readiness
The section names
@datadog/openfeature-browser2.2.0, the first release that includesflagSelection, as the minimum version.AI assistance
Drafted with Claude Code from the SDK README and source; reviewed against the SDK behavior.
For Datadog employees:
<name>/<description>convention and include the forward slash (/). If you've already created your PR with an incorrect branch name, please rename your branch and open a fresh PR./reviewto run an automated check that catches common issues before a Documentation team member reviews your PR.Additional notes
Other client SDK pages and the API reference are not part of this PR.
🤖 Generated with Claude Code