Angularv1.2.1Frontend

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-angular

Quick Start

1. Import the Module

Add RollgateModule to your root module using forRoot():

app.module.ts
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:

feature.component.ts
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:

feature.component.html
<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():

OptionTypeDefaultDescription
apiKeystringrequiredYour Rollgate client API key
baseUrlstring'https://api.rollgate.io'Rollgate API base URL
refreshIntervalnumber30000Polling interval in milliseconds
enableStreamingbooleanfalseUse SSE for real-time updates (opt-in)
streamingbooleanfalseAlias for enableStreaming
userUserContextundefinedInitial user context for targeting
Full configuration example
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);
OptionTypeDefaultDescription
flagKeystringrequiredThe flag key to check
defaultValuebooleanfalseValue to return if flag not found

getValue

Get the value of a flag (for multivariate flags):

const value = this.rollgate.getValue('button-color', 'blue');
OptionTypeDefaultDescription
flagKeystringrequiredThe flag key to check
defaultValuestringrequiredValue 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:

reactive.component.ts
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:

main.ts
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',
    }),
  ],
});
feature.component.ts
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');