From 6d012149da1a1cee2def656c7265580a85388b22 Mon Sep 17 00:00:00 2001 From: Dmytrii Puzyr Date: Wed, 4 Feb 2026 16:59:37 +0200 Subject: [PATCH 1/6] FFL-917 Add documentation for the Flags SDK for React Native --- config/_default/menus/main.en.yaml | 5 + .../en/feature_flags/client/reactnative.md | 484 ++++++++++++++++++ .../feature_flags/feature_flags_client.html | 7 + 3 files changed, 496 insertions(+) create mode 100644 content/en/feature_flags/client/reactnative.md diff --git a/config/_default/menus/main.en.yaml b/config/_default/menus/main.en.yaml index 4383ff50d52..2bf1cf89770 100644 --- a/config/_default/menus/main.en.yaml +++ b/config/_default/menus/main.en.yaml @@ -5766,6 +5766,11 @@ menu: parent: feature_flags_client identifier: feature_flags_client_react weight: 104 + - name: React Native + url: feature_flags/client/reactnative + parent: feature_flags_client + identifier: feature_flags_client_react_native + weight: 105 - name: Server SDKs url: feature_flags/server parent: feature_flags diff --git a/content/en/feature_flags/client/reactnative.md b/content/en/feature_flags/client/reactnative.md new file mode 100644 index 00000000000..3ec40ca116e --- /dev/null +++ b/content/en/feature_flags/client/reactnative.md @@ -0,0 +1,484 @@ +--- +title: React Native Feature Flags +description: Set up Datadog Feature Flags for React Native applications. +further_reading: +- link: "/feature_flags/client/" + tag: "Documentation" + text: "Client-Side Feature Flags" +- link: "https://openfeature.dev/docs/reference/sdks/client/web/react/" + tag: "OpenFeature" + text: "OpenFeature React SDK" +- link: "/real_user_monitoring/application_monitoring/react_native/" + tag: "Documentation" + text: "React Native Monitoring" +--- + +## Overview + +This page describes how to instrument your React Native application with the Datadog Feature Flags SDK. Datadog feature flags provide a unified way to remotely control feature availability in your app, experiment safely, and deliver new experiences with confidence. + +The Datadog Feature Flags SDK for React Native is built on [OpenFeature][1], an open standard for feature flag management. This guide explains how to install the SDK, configure the Datadog provider, and evaluate flags in your React Native components. + +## Requirements + +- React Native v0.65+ +- iOS: iOS 13+ +- Android: API level 23+ +- Datadog React Native SDK (`@datadog/mobile-react-native`) must be initialized first + +## Installation + +Install the Datadog React Native SDK, the OpenFeature provider, and the OpenFeature React SDK using your preferred package manager: + +{{< tabs >}} +{{% tab "npm" %}} +{{< code-block lang="bash" >}} +npm install @datadog/mobile-react-native @datadog/mobile-react-native-openfeature @openfeature/react-sdk +{{< /code-block >}} +{{% /tab %}} + +{{% tab "yarn" %}} +{{< code-block lang="bash" >}} +yarn add @datadog/mobile-react-native @datadog/mobile-react-native-openfeature @openfeature/react-sdk +{{< /code-block >}} +{{% /tab %}} +{{< /tabs >}} + +### iOS setup + +Install the added pod: + +{{< code-block lang="bash" >}} +(cd ios && pod install) +{{< /code-block >}} + +### Android setup + +If you use a React Native version strictly over 0.67, use Java version 17. If you use React Native version equal or below 0.67, use Java version 11. + +In your `android/build.gradle` file, specify the `kotlinVersion` to avoid clashes among kotlin dependencies: + +{{< code-block lang="groovy" filename="build.gradle" >}} +buildscript { + ext { + kotlinVersion = "1.8.21" + } +} +{{< /code-block >}} + +## Initialize the SDK + +The Datadog OpenFeature provider for React Native requires the core Datadog SDK to be initialized first, followed by enabling the Feature Flags feature. + +### Option 1: Using DatadogProvider component + +If you use the `DatadogProvider` component for SDK initialization, enable Feature Flags in the `onInitialized` callback: + +```tsx +import { DatadogProvider, DatadogProviderConfiguration, DdFlags } from '@datadog/mobile-react-native'; +import { DatadogOpenFeatureProvider } from '@datadog/mobile-react-native-openfeature'; +import { OpenFeature, OpenFeatureProvider } from '@openfeature/react-sdk'; + +const config = new DatadogProviderConfiguration( + '', + '', + '', + true, // trackInteractions + true, // trackResources + true // trackErrors +); +config.site = '{{< region-param key="dd_site" code="true" >}}'; + +export default function App() { + return ( + { + await DdFlags.enable(); + + const provider = new DatadogOpenFeatureProvider(); + OpenFeature.setProvider(provider); + }} + > + + + + + ); +} +``` + +### Option 2: Using imperative initialization + +If you initialize the SDK imperatively, enable Feature Flags after initialization completes: + +```tsx +import { DdSdkReactNative, DdFlags, CoreConfiguration } from '@datadog/mobile-react-native'; +import { DatadogOpenFeatureProvider } from '@datadog/mobile-react-native-openfeature'; +import { OpenFeature } from '@openfeature/react-sdk'; + +(async () => { + const config = new CoreConfiguration( + '', + '', + '' + ); + config.site = '{{< region-param key="dd_site" code="true" >}}'; + + await DdSdkReactNative.initialize(config); + + // Enable Feature Flags after core SDK initialization + await DdFlags.enable(); + + // Set the Datadog provider with OpenFeature + const provider = new DatadogOpenFeatureProvider(); + OpenFeature.setProvider(provider); +})(); +``` + +
Sending flag evaluation data to Datadog is automatically enabled when using the Feature Flags SDK. Provide rumIntegrationEnabled and trackExposures parameters to the DdFlags.enable() call to configure this behavior.
+ +## Set the evaluation context + +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. + +{{< code-block lang="javascript" >}} +import { OpenFeature } from '@openfeature/react-sdk'; + +const evaluationContext = { + targetingKey: 'user-123', + user_id: '123', + email: 'user@example.com', + tier: 'premium', +}; + +OpenFeature.setContext(evaluationContext); +{{< /code-block >}} + +
The targetingKey is used as the randomization subject for percentage-based targeting. When a flag targets a percentage of subjects (for example, 50%), the targetingKey determines which "bucket" a user falls into. Users with the same targetingKey always receive the same variant for a given flag.
+ +## Wrap your application + +Wrap your application with the `OpenFeatureProvider` component. This makes feature flags available to all child components through React context. + +{{< code-block lang="tsx" >}} +import { OpenFeatureProvider } from '@openfeature/react-sdk'; + +function App() { + return ( + + + + ); +} +{{< /code-block >}} + +## Evaluate flags + +The OpenFeature React SDK provides hooks for evaluating flags within your components. Each hook returns the flag value based on the evaluation context you configured. Flag evaluation is _local and instantaneous_—the SDK uses locally cached data, so no network requests occur when evaluating flags. + +### Boolean flags + +Use `useBooleanFlagValue(key, defaultValue)` for flags that represent on/off or true/false conditions: + +{{< code-block lang="jsx" >}} +import { useBooleanFlagValue } from '@openfeature/react-sdk'; + +function CheckoutButton() { + const isNewCheckoutEnabled = useBooleanFlagValue('new_checkout_button', false); + + if (isNewCheckoutEnabled) { + return ; + } + + return ; +} +{{< /code-block >}} + +### String flags + +Use `useStringFlagValue(key, defaultValue)` for flags that select between multiple variants or configuration strings: + +{{< code-block lang="jsx" >}} +import { useStringFlagValue } from '@openfeature/react-sdk'; + +function ThemedComponent() { + const theme = useStringFlagValue('ui_theme', 'light'); + + switch (theme) { + case 'dark': + return ; + case 'light': + default: + return ; + } +} +{{< /code-block >}} + +### Number flags + +Use `useNumberFlagValue(key, defaultValue)` for numeric flags such as limits, percentages, or multipliers: + +{{< code-block lang="jsx" >}} +import { useNumberFlagValue } from '@openfeature/react-sdk'; + +function CartDisplay() { + const maxItems = useNumberFlagValue('max_cart_items', 20); + + return ; +} +{{< /code-block >}} + +### Object flags + +Use `useObjectFlagValue(key, defaultValue)` for structured configuration data: + +{{< code-block lang="jsx" >}} +import { useObjectFlagValue } from '@openfeature/react-sdk'; + +function Banner() { + const config = useObjectFlagValue('promo_banner', { + color: '#00A3FF', + message: 'Welcome!', + }); + + return ; +} +{{< /code-block >}} + +### Suspense support + +Built-in [suspense](https://react.dev/reference/react/Suspense) support allows you to avoid displaying components with feature flags until provider initialization is complete, or when the context changes. Pass `{ suspend: true }` in the hook options to use this functionality. + +For example: + +{{< code-block lang="jsx" >}} +import { useBooleanFlag } from '@openfeature/react-sdk'; +import { Suspense } from 'react'; + +import +function Content() { + // Display a loading message if the component uses feature flags and the provider is not ready + return ( + + + + ); +} + +function WelcomeMessage() { + const { value: showNewMessage } = useBooleanFlag('show-new-welcome-message', false, { suspend: true }); + + return ( + <> + {showNewMessage ? ( +

Welcome! You're seeing the new experience.

+ ) : ( +

Welcome back!

+ )} + + ); +} +{{< /code-block >}} + +### Flag evaluation details + +When you need more than just the flag value, use the detail hooks. These return both the evaluated value and metadata explaining the evaluation: + +* `useBooleanFlagDetails(key, defaultValue)` +* `useStringFlagDetails(key, defaultValue)` +* `useNumberFlagDetails(key, defaultValue)` +* `useObjectFlagDetails(key, defaultValue)` + +For example: + +{{< code-block lang="jsx" >}} +import { useStringFlagDetails } from '@openfeature/react-sdk'; + +function PaywallLayout() { + const details = useStringFlagDetails('paywall_layout', 'control'); + + console.log(details.value); // Evaluated value (for example: "A", "B", or "control") + console.log(details.variant); // Variant name, if applicable + console.log(details.reason); // Description of why this value was chosen + + return ; +} +{{< /code-block >}} + +Flag details help you debug evaluation behavior and understand why a user received a given value. + +## Complete example + +Here's a complete example showing how to set up and use Datadog Feature Flags in a React Native application: + +```tsx +import { Suspense } from 'react'; +import { View } from 'react-native'; +import { DatadogProvider, DatadogProviderConfiguration, DdFlags } from '@datadog/mobile-react-native'; +import { DatadogOpenFeatureProvider } from '@datadog/mobile-react-native-openfeature'; +import { OpenFeature, OpenFeatureProvider, useFlag } from '@openfeature/react-sdk'; + +const config = new DatadogProviderConfiguration( + '', + '', + trackingConsent, + { + rumConfiguration: { + applicationId: '', + }, + // ... + }, +); + +// Wrap your app with the DatadogProvider and OpenFeatureProvider. +export default function AppWithProviders() { + // Based on your auth state. + const user = getCurrentUser(); + + return ( + { + await DdFlags.enable(); + + const provider = new DatadogOpenFeatureProvider(); + + const evaluationContext = { + targetingKey: user.id, + region: user.country, + }; + + OpenFeature.setProvider(provider, evaluationContext); + }} + > + }> + + + + + + ); +} + +// Use feature flags in your components +function App() { + const showNewFeature = useBooleanFlagValue('new_feature', false); + + return ( + + {showNewFeature ? : } + + ); +} +``` + +## Update the evaluation context + +To update the evaluation context after initialization (for example, when a user logs in), use `OpenFeature.setContext()`: + +{{< code-block lang="tsx" >}} +import { OpenFeature } from '@openfeature/react-sdk'; + +// When a user logs in +function onUserLogin(user) { + OpenFeature.setContext({ + targetingKey: user.id, + email: user.email, + plan: user.plan, + }); +} +{{< /code-block >}} + +## Configure Feature Flags options + +Pass configuration options to `DdFlags.enable()` to customize Feature Flags behavior: + +{{< code-block lang="tsx" >}} +await DdFlags.enable({ + // Send flag evaluation data to RUM for session analysis (default: true) + rumIntegrationEnabled: true, + // Track flag exposures for analytics (default: true) + trackExposures: true, +}); +{{< /code-block >}} + +`rumIntegrationEnabled` +: When `true` (default), flag evaluations are tracked in RUM, which enables correlating them with user sessions. This enables analytics such as _"Do users in variant B experience more errors?"_. + +`trackExposures` +: When `true` (default), the SDK automatically records an _exposure event_ when a flag is evaluated. These events contain metadata about which flag was accessed, which variant was served, and under what context. They are sent to Datadog so you can analyze feature adoption. + +## Context attribute requirements + +
+Evaluation context attributes must be flat primitive values (strings, numbers, booleans). Nested objects and arrays are not supported and cause exposure events to be silently dropped. +
+ +Use flat attributes in your evaluation context: + +{{< code-block lang="javascript" >}} +OpenFeature.setContext({ + targetingKey: 'user-123', + userId: 'user-123', + tier: 'premium', + age: 25 +}); +{{< /code-block >}} + +Avoid nested objects and arrays: + +{{< code-block lang="javascript" >}} +// These attributes cause exposure events to be dropped +OpenFeature.setContext({ + targetingKey: 'user-123', + user: { id: 'user-123' }, // nested object - NOT SUPPORTED + features: ['beta', 'analytics'] // array - NOT SUPPORTED +}); +{{< /code-block >}} + +## Troubleshooting + +### No flags returned + +If flag evaluations return default values: + +1. Verify the Datadog SDK is initialized before calling `DdFlags.enable()`. +2. Confirm `DdFlags.enable()` completed before setting the OpenFeature provider. +3. Check that the evaluation context is set before evaluating flags. +4. Confirm the flag exists and is enabled in your Datadog Feature Flags dashboard. + +### iOS pod install errors + +If you have `use_frameworks!` enabled in your `Podfile`, you may see errors during `pod install`. Edit your `Podfile` to install the SDK pod as a static library: + +{{< code-block lang="ruby" filename="Podfile" >}} +static_libraries = ['DatadogSDKReactNative'] + +pre_install do |installer| + installer.pod_targets.each do |pod| + if static_libraries.include?(pod.name) + def pod.static_framework?; + true + end + def pod.build_type; + Pod::BuildType.static_library + end + end + end +end +{{< /code-block >}} + +### Feature Flags not initialized error + +If you see an error about Feature Flags not being initialized, verify the initialization order: + +1. Initialize the core Datadog SDK first (`DdSdkReactNative.initialize()` or `DatadogProvider`) +2. Call `DdFlags.enable()` after SDK initialization +3. Create and set the `DatadogOpenFeatureProvider` after enabling flags + +## Further reading + +{{< partial name="whats-next/whats-next.html" >}} + +[1]: https://openfeature.dev/ diff --git a/layouts/partials/feature_flags/feature_flags_client.html b/layouts/partials/feature_flags/feature_flags_client.html index 15a4a3dec56..1863af5eed5 100644 --- a/layouts/partials/feature_flags/feature_flags_client.html +++ b/layouts/partials/feature_flags/feature_flags_client.html @@ -16,6 +16,13 @@ +
From c5f20a51b60e3f4e0ddde4b8a951e524872781f9 Mon Sep 17 00:00:00 2001 From: Dmytrii Puzyr Date: Mon, 9 Feb 2026 13:27:06 +0200 Subject: [PATCH 2/6] Fix usage examples --- content/en/feature_flags/client/reactnative.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/content/en/feature_flags/client/reactnative.md b/content/en/feature_flags/client/reactnative.md index 3ec40ca116e..d130b4590e5 100644 --- a/content/en/feature_flags/client/reactnative.md +++ b/content/en/feature_flags/client/reactnative.md @@ -82,10 +82,13 @@ import { OpenFeature, OpenFeatureProvider } from '@openfeature/react-sdk'; const config = new DatadogProviderConfiguration( '', '', - '', - true, // trackInteractions - true, // trackResources - true // trackErrors + trackingConsent, + { + rumConfiguration: { + applicationId: '', + }, + // ... + }, ); config.site = '{{< region-param key="dd_site" code="true" >}}'; @@ -256,7 +259,6 @@ For example: import { useBooleanFlag } from '@openfeature/react-sdk'; import { Suspense } from 'react'; -import function Content() { // Display a loading message if the component uses feature flags and the provider is not ready return ( From 5f6abac72a94eedfc7801443c953823c2e3277bf Mon Sep 17 00:00:00 2001 From: Dmytrii Puzyr Date: Mon, 9 Feb 2026 13:27:26 +0200 Subject: [PATCH 3/6] Add alias for the /setup/ page --- content/en/feature_flags/client/reactnative.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/en/feature_flags/client/reactnative.md b/content/en/feature_flags/client/reactnative.md index d130b4590e5..805bf80b0ec 100644 --- a/content/en/feature_flags/client/reactnative.md +++ b/content/en/feature_flags/client/reactnative.md @@ -1,6 +1,8 @@ --- title: React Native Feature Flags description: Set up Datadog Feature Flags for React Native applications. +aliases: + - /feature_flags/setup/reactnative/ further_reading: - link: "/feature_flags/client/" tag: "Documentation" From 60c23e1ecb7126ff2def9ee35a2db2298e2d7dbb Mon Sep 17 00:00:00 2001 From: Dmytrii Puzyr Date: Mon, 9 Feb 2026 13:53:58 +0200 Subject: [PATCH 4/6] Add openfeature SDK peer deps to the install code block --- content/en/feature_flags/client/reactnative.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/feature_flags/client/reactnative.md b/content/en/feature_flags/client/reactnative.md index 805bf80b0ec..99ac590769c 100644 --- a/content/en/feature_flags/client/reactnative.md +++ b/content/en/feature_flags/client/reactnative.md @@ -35,13 +35,13 @@ Install the Datadog React Native SDK, the OpenFeature provider, and the OpenFeat {{< tabs >}} {{% tab "npm" %}} {{< code-block lang="bash" >}} -npm install @datadog/mobile-react-native @datadog/mobile-react-native-openfeature @openfeature/react-sdk +npm install @datadog/mobile-react-native @datadog/mobile-react-native-openfeature @openfeature/react-sdk @openfeature/web-sdk @openfeature/core {{< /code-block >}} {{% /tab %}} {{% tab "yarn" %}} {{< code-block lang="bash" >}} -yarn add @datadog/mobile-react-native @datadog/mobile-react-native-openfeature @openfeature/react-sdk +yarn add @datadog/mobile-react-native @datadog/mobile-react-native-openfeature @openfeature/react-sdk @openfeature/web-sdk @openfeature/core {{< /code-block >}} {{% /tab %}} {{< /tabs >}} From 27370c6676b80aa8f42e6c8302720fd0d39fedf3 Mon Sep 17 00:00:00 2001 From: Dmytrii Puzyr Date: Mon, 9 Feb 2026 13:58:41 +0200 Subject: [PATCH 5/6] More fixes --- content/en/feature_flags/client/reactnative.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/en/feature_flags/client/reactnative.md b/content/en/feature_flags/client/reactnative.md index 99ac590769c..abb66653f34 100644 --- a/content/en/feature_flags/client/reactnative.md +++ b/content/en/feature_flags/client/reactnative.md @@ -4,12 +4,12 @@ description: Set up Datadog Feature Flags for React Native applications. aliases: - /feature_flags/setup/reactnative/ further_reading: -- link: "/feature_flags/client/" - tag: "Documentation" - text: "Client-Side Feature Flags" - link: "https://openfeature.dev/docs/reference/sdks/client/web/react/" tag: "OpenFeature" text: "OpenFeature React SDK" +- link: "/feature_flags/client/" + tag: "Documentation" + text: "Client-Side Feature Flags" - link: "/real_user_monitoring/application_monitoring/react_native/" tag: "Documentation" text: "React Native Monitoring" @@ -56,7 +56,7 @@ Install the added pod: ### Android setup -If you use a React Native version strictly over 0.67, use Java version 17. If you use React Native version equal or below 0.67, use Java version 11. +If you use React Native version 0.68 or higher, use Java 17. If you use React Native version 0.67 or lower, use Java version 11. In your `android/build.gradle` file, specify the `kotlinVersion` to avoid clashes among kotlin dependencies: @@ -258,7 +258,7 @@ Built-in [suspense](https://react.dev/reference/react/Suspense) support allows y For example: {{< code-block lang="jsx" >}} -import { useBooleanFlag } from '@openfeature/react-sdk'; +import { useBooleanFlagValue } from '@openfeature/react-sdk'; import { Suspense } from 'react'; function Content() { @@ -271,7 +271,7 @@ function Content() { } function WelcomeMessage() { - const { value: showNewMessage } = useBooleanFlag('show-new-welcome-message', false, { suspend: true }); + const { value: showNewMessage } = useBooleanFlagValue('show-new-welcome-message', false, { suspend: true }); return ( <> @@ -321,7 +321,7 @@ import { Suspense } from 'react'; import { View } from 'react-native'; import { DatadogProvider, DatadogProviderConfiguration, DdFlags } from '@datadog/mobile-react-native'; import { DatadogOpenFeatureProvider } from '@datadog/mobile-react-native-openfeature'; -import { OpenFeature, OpenFeatureProvider, useFlag } from '@openfeature/react-sdk'; +import { OpenFeature, OpenFeatureProvider, useBooleanFlagValue } from '@openfeature/react-sdk'; const config = new DatadogProviderConfiguration( '', From 53d6995c1796aab3e76ad0ed35f7669a266863f2 Mon Sep 17 00:00:00 2001 From: Dmytrii Puzyr Date: Wed, 11 Feb 2026 17:28:40 +0200 Subject: [PATCH 6/6] Fix mentions of nested obj properties on evaluation context --- content/en/feature_flags/client/reactnative.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/feature_flags/client/reactnative.md b/content/en/feature_flags/client/reactnative.md index abb66653f34..1d79814b307 100644 --- a/content/en/feature_flags/client/reactnative.md +++ b/content/en/feature_flags/client/reactnative.md @@ -416,7 +416,7 @@ await DdFlags.enable({ ## Context attribute requirements
-Evaluation context attributes must be flat primitive values (strings, numbers, booleans). Nested objects and arrays are not supported and cause exposure events to be silently dropped. +Evaluation context attributes must be flat primitive values (strings, numbers, booleans). Nested objects and arrays are not supported and will be dropped from the evaluation context.
Use flat attributes in your evaluation context: @@ -433,7 +433,7 @@ OpenFeature.setContext({ Avoid nested objects and arrays: {{< code-block lang="javascript" >}} -// These attributes cause exposure events to be dropped +// These attributes will be dropped from the evaluation context with a console warning. OpenFeature.setContext({ targetingKey: 'user-123', user: { id: 'user-123' }, // nested object - NOT SUPPORTED