Angular SDK
Add feature flags to your Angular application with modules, services, and pipes. Wraps @rollgate/sdk-browser with idiomatic Angular patterns including dependency injection and template pipes.
Installation
npm install @rollgate/sdk-angular
# or
yarn add @rollgate/sdk-angular
# or
pnpm add @rollgate/sdk-angularQuick Start
1. Import the Module
Add RollgateModule to your root module using forRoot():
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RollgateModule } from '@rollgate/sdk-angular';
import { environment } from '../environments/environment';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
RollgateModule.forRoot({
apiKey: environment.rollgateApiKey,
baseUrl: 'https://api.rollgate.io',
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}2. Inject the Service
Use RollgateService in your components via dependency injection:
import { Component } from '@angular/core';
import { RollgateService } from '@rollgate/sdk-angular';
@Component({
selector: 'app-feature',
template: `
<div *ngIf="showFeature">
<h2>New Feature</h2>
<p>This content is behind a feature flag.</p>
</div>
`,
})
export class FeatureComponent {
constructor(private rollgate: RollgateService) {}
get showFeature(): boolean {
return this.rollgate.isEnabled('my-feature', false);
}
}3. Use the Pipe in Templates
For a cleaner template syntax, use the rollgateFlag pipe directly:
<div *ngIf="'my-feature' | rollgateFlag">
<h2>New Feature</h2>
<p>This content is behind a feature flag.</p>
</div>
<!-- With else template -->
<div *ngIf="'beta-dashboard' | rollgateFlag; else oldDashboard">
<app-new-dashboard />
</div>
<ng-template #oldDashboard>
<app-legacy-dashboard />
</ng-template>Configuration
Pass configuration options to RollgateModule.forRoot():
| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | string | required | Your Rollgate client API key |
| baseUrl | string | 'https://api.rollgate.io' | Rollgate API base URL |
| refreshInterval | number | 30000 | Polling interval in milliseconds |
| enableStreaming | boolean | false | Use SSE for real-time updates (opt-in) |
| streaming | boolean | false | Alias for enableStreaming |
| user | UserContext | undefined | Initial user context for targeting |
RollgateModule.forRoot({
apiKey: environment.rollgateApiKey,
baseUrl: 'https://api.rollgate.io',
refreshInterval: 15000,
enableStreaming: true,
user: {
id: 'user-123',
email: '[email protected]',
attributes: { plan: 'pro' },
},
})RollgateService API
The RollgateService is an injectable Angular service that provides access to all flag operations.
isEnabled
Check if a single flag is enabled:
const isEnabled = this.rollgate.isEnabled('flag-key', defaultValue);| Option | Type | Default | Description |
|---|---|---|---|
| flagKey | string | required | The flag key to check |
| defaultValue | boolean | false | Value to return if flag not found |
getValue
Get the value of a flag (for multivariate flags):
const value = this.rollgate.getValue('button-color', 'blue');| Option | Type | Default | Description |
|---|---|---|---|
| flagKey | string | required | The flag key to check |
| defaultValue | string | required | Value to return if flag not found |
identify
Set user context for targeted flag evaluation:
await this.rollgate.identify({
id: 'user-123',
email: '[email protected]',
attributes: { plan: 'pro' },
});refresh
Force a manual refresh of all flags:
await this.rollgate.refresh();flags$ Observable
Subscribe to flag changes reactively using the flags$ observable:
import { Component, OnInit } from '@angular/core';
import { RollgateService } from '@rollgate/sdk-angular';
@Component({
selector: 'app-reactive',
template: `
<div *ngIf="flags$ | async as flags">
<app-new-feature *ngIf="flags['new-feature']" />
</div>
`,
})
export class ReactiveComponent {
flags$ = this.rollgate.flags$;
constructor(private rollgate: RollgateService) {}
}rollgateFlag Pipe
The rollgateFlag pipe provides a convenient way to check flags directly in templates. It is automatically available when you import RollgateModule.
<!-- Boolean check -->
<div *ngIf="'feature-key' | rollgateFlag">
Feature is enabled
</div>
<!-- With structural directive -->
<ng-container *ngIf="'premium-feature' | rollgateFlag">
<app-premium-content />
</ng-container>
<!-- In attribute binding -->
<button [disabled]="!('submit-enabled' | rollgateFlag)">
Submit
</button>User Targeting
Pass user information to enable targeting rules, percentage rollout, and target user lists. The SDK sends this context to the server where rules are evaluated securely.
User Context Structure
interface UserContext {
id: string; // Required for percentage rollout
email?: string; // For email-based targeting
attributes?: { // Any custom attributes for targeting rules
plan?: string; // e.g., "free", "pro", "growth"
country?: string; // e.g., "IT", "US", "DE"
company?: string; // e.g., "Acme Inc"
app_version?: string; // e.g., "2.1.0" (for semver comparisons)
[key: string]: string | number | boolean;
};
}Setting User Context
// Option 1: In module config (known user at startup)
RollgateModule.forRoot({
apiKey: environment.rollgateApiKey,
user: {
id: 'user-123',
email: '[email protected]',
attributes: {
plan: 'pro',
country: 'IT',
company: 'Acme Inc',
app_version: '2.1.0'
}
}
})
// Option 2: After authentication (dynamic)
@Component({ ... })
export class AppComponent implements OnInit {
constructor(
private rollgate: RollgateService,
private auth: AuthService,
) {}
ngOnInit() {
this.auth.user$.subscribe(user => {
if (user) {
this.rollgate.identify({
id: user.id,
email: user.email,
attributes: {
plan: user.subscription.plan,
country: user.profile.country,
company: user.organization?.name,
app_version: APP_VERSION
}
});
}
});
}
}Targeting Rules Example
With the user context above, your targeting rules can match on any attribute:
Example: Pro Italian Users on v2+
Dashboard rule configuration:
Rule: "Pro Italian Users on v2+"
Conditions (all must match):
- plan IN "pro,growth"
- country EQUALS "IT"
- app_version SEMVER_GTE "2.0.0"
// This user will match:
{
id: "user-123",
attributes: {
plan: "pro", // matches: in [pro, growth]
country: "IT", // matches: equals IT
app_version: "2.1.0" // matches: >= 2.0.0
}
}Security: Rules are evaluated server-side. Users cannot see or manipulate the targeting logic - they only receive the final boolean result.
Standalone Components
If you are using Angular standalone components, you can import RollgateModule directly:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRollgate } from '@rollgate/sdk-angular';
import { environment } from './environments/environment';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [
provideRollgate({
apiKey: environment.rollgateApiKey,
baseUrl: 'https://api.rollgate.io',
}),
],
});import { Component } from '@angular/core';
import { RollgateFlagPipe } from '@rollgate/sdk-angular';
import { NgIf } from '@angular/common';
@Component({
selector: 'app-feature',
standalone: true,
imports: [NgIf, RollgateFlagPipe],
template: `
<div *ngIf="'my-feature' | rollgateFlag">
New feature content
</div>
`,
})
export class FeatureComponent {}TypeScript
The SDK is fully typed. Define your flag keys for type safety:
// types/flags.ts
export type FlagKey =
| 'new-checkout'
| 'dark-mode'
| 'beta-features';
// Usage in component
const isEnabled = this.rollgate.isEnabled<FlagKey>('new-checkout');