For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/feature_flags/client/angular.md.
A documentation index is available at /llms.txt.
This product is not supported for your selected Datadog site. ().
Overview
This page describes how to instrument your Angular 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 Angular is built on OpenFeature, an open standard for feature flag management. This guide explains how to install the SDK, configure the Datadog provider, and evaluate flags in your Angular components using structural directives or the FeatureFlagService.
Requirements
Angular version 16 or later
ECMAScript 2015-compatible web browser such as Chrome, Edge, or Firefox
Installation
Install the Datadog OpenFeature provider and the OpenFeature Angular SDK using your preferred package manager:
Create a DatadogProvider instance with your Datadog credentials. For live Browser Feature Flags configuration, applicationId, clientToken, site, and env are required. To create a client token, see Client tokens.
Browser Feature Flags are not supported for the selected Datadog site ().
Import the OpenFeatureModule in your Angular module and configure it using the forRoot method. This makes feature flags available throughout your application.
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.
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.
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.
import{NgModule}from'@angular/core';import{CommonModule}from'@angular/common';import{OpenFeatureModule,EvaluationContext}from'@openfeature/angular-sdk';import{DatadogProvider}from'@datadog/openfeature-browser';constprovider=newDatadogProvider({applicationId:'<APPLICATION_ID>',clientToken:'<CLIENT_TOKEN>',site:'',env:'<ENV_NAME>',});@NgModule({imports:[CommonModule,OpenFeatureModule.forRoot({provider: provider,context:():EvaluationContext=>{// Load context from your service, localStorage, or other source
// This is a placeholder - implement based on your application's needs
returnloadContextFromLocalStorage();},}),],});exportclassAppModule{}
Update the evaluation context
To update the evaluation context after initialization (for example, when a user logs in), use OpenFeature.setContext():
The OpenFeature Angular SDK provides two main ways to work with feature flags:
Structural Directives - For template-based conditional rendering
FeatureFlagService - For programmatic access with Observables or Signals
Boolean flags
Use Boolean flags for on/off or true/false conditions.
<div*booleanFeatureFlag="'isFeatureEnabled'; default: true; domain: 'userDomain'; else: booleanFeatureElse; initializing: booleanFeatureInitializing; reconciling: booleanFeatureReconciling"> This is shown when the feature flag is enabled.
</div><ng-template#booleanFeatureElse> This is shown when the feature flag is disabled. </ng-template><ng-template#booleanFeatureInitializing> This is shown when the feature flag is initializing. </ng-template><ng-template#booleanFeatureReconciling> This is shown when the feature flag is reconciling. </ng-template>
Use string flags to select between multiple variants or configuration strings.
<div*stringFeatureFlag="'themeColor'; value: 'dark'; default: 'light'; domain: 'userDomain'; else: stringFeatureElse; initializing: stringFeatureInitializing; reconciling: stringFeatureReconciling"> This is shown when the feature flag matches the specified theme color.
</div><ng-template#stringFeatureElse> This is shown when the feature flag does not match the specified theme color. </ng-template><ng-template#stringFeatureInitializing> This is shown when the feature flag is initializing. </ng-template><ng-template#stringFeatureReconciling> This is shown when the feature flag is reconciling. </ng-template>
Use number flags for numeric values such as limits, percentages, or multipliers.
<div*numberFeatureFlag="'discountRate'; value: 10; default: 5; domain: 'userDomain'; else: numberFeatureElse; initializing: numberFeatureInitializing; reconciling: numberFeatureReconciling"> This is shown when the feature flag matches the specified discount rate.
</div><ng-template#numberFeatureElse> This is shown when the feature flag does not match the specified discount rate. </ng-template><ng-template#numberFeatureInitializing> This is shown when the feature flag is initializing. </ng-template><ng-template#numberFeatureReconciling> This is shown when the feature flag is reconciling. </ng-template>
Use object flags for structured configuration data.
<div*objectFeatureFlag="'userConfig'; value: { theme: 'dark' }; default: { theme: 'light' }; domain: 'userDomain'; else: objectFeatureElse; initializing: objectFeatureInitializing; reconciling: objectFeatureReconciling"> This is shown when the feature flag matches the specified user configuration.
</div><ng-template#objectFeatureElse> This is shown when the feature flag does not match the specified user configuration.
</ng-template><ng-template#objectFeatureInitializing> This is shown when the feature flag is initializing. </ng-template><ng-template#objectFeatureReconciling> This is shown when the feature flag is reconciling. </ng-template>
By default, directives re-render when the flag value changes or the context changes. You can disable this behavior:
<div*booleanFeatureFlag="'isFeatureEnabled'; default: true; updateOnContextChanged: false; updateOnConfigurationChanged: false;"> This is shown when the feature flag is enabled.
</div>
The service methods also accept options to control automatic updates:
You can access the evaluation details in your templates:
<div*stringFeatureFlag="'themeColor'; value: 'dark'; default: 'light'; else: stringFeatureElse; let value; let details = evaluationDetails"> It was a match! The theme color is {{ value }} because of {{ details.reason }}
</div><ng-template#stringFeatureElselet-valuelet-details="evaluationDetails"> It was no match! The theme color is {{ value }} because of {{ details.reason }}
</ng-template>
When the expected flag value is omitted, the template is always rendered. This can be used to only render the flag value or details without conditional rendering:
<div*stringFeatureFlag="'themeColor'; default: 'light'; let value;"> The theme color is {{ value }}.
</div>
When using the service, the detail methods return both the evaluated value and metadata explaining the evaluation:
import{Component,inject}from'@angular/core';import{toSignal}from'@angular/core/rxjs-interop';import{FeatureFlagService}from'@openfeature/angular-sdk';@Component({selector:'my-component',standalone: true,template:`
<div *ngIf="details()?.value">
Feature is enabled! Variant: {{ details()?.variant }}, Reason: {{ details()?.reason }}
</div>
`,})exportclassMyComponent{privateflagService=inject(FeatureFlagService);details=toSignal(this.flagService.getBooleanDetails('my-feature',false));// Access the details
// details().value // Evaluated value (true or false)
// details().variant // Variant name, if applicable
// details().reason // Why this value was chosen
// details().errorCode // Error code, if evaluation failed
}
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 when Browser RUM is available. Enabling this option can increase RUM-billed event counts.
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, which is already installed for Angular Feature Flags.
import{TestBed}from'@angular/core/testing';import{firstValueFrom}from'rxjs';import{FeatureFlagService,OpenFeatureModule}from'@openfeature/angular-sdk';import{TypedInMemoryProvider}from'@openfeature/web-sdk';constflags={new_checkout_button:{variants:{on: true,off: false},defaultVariant:'on',disabled: false,},};beforeEach(async()=>{awaitTestBed.configureTestingModule({imports:[OpenFeatureModule.forRoot({provider: newTypedInMemoryProvider(flags),context:{targetingKey:'test-user'},}),],}).compileComponents();});afterEach(()=>{TestBed.resetTestingModule();});it('uses in-memory flag values',async()=>{constflagService=TestBed.inject(FeatureFlagService);constdetails=awaitfirstValueFrom(flagService.getBooleanDetails('new_checkout_button',false));expect(details.value).toBe(true);});
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
Additional helpful documentation, links, and articles: