On this page

Statsig in Angular

Statsig's SDK for Experimentation and Feature Flags in Angular applications.

Set Up the SDK

  1. Install the SDK

    npm install @statsig/angular-bindings
    
  2. Initialize the SDK

    Next, initialize the SDK with a client SDK key from the "API Keys" tab on the Statsig console. These keys are safe to embed in a client application.Along with the key, pass in a User Object with the attributes you'd like to target later on in a gate or experiment.

    The Statsig Angular bindings package provides a StatsigService that you can inject into your components. The way you provide and inject this service can vary depending on how you structure your app.

    ts
    import { STATSIG_INIT_CONFIG } from '@statsig/angular-bindings';
    
    const StatsigConfig = {
            sdkKey: "client-KEY",
            user: {}, // initial user object
            options: {...} // optional
    }
    

    Using app config

    ts
    // app.config.ts
    import { ApplicationConfig } from '@angular/core';
    import { STATSIG_INIT_CONFIG } from '@statsig/angular-bindings';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        {
          provide: STATSIG_INIT_CONFIG,
          useValue: StatsigConfig,
        },
      ],
    };
    
    //main.ts
    import { AppComponent } from './app/app.component';
    import { appConfig } from './app/app.config';
    
    bootstrapApplication(AppComponent, appConfig).catch((err) =>
      console.error(err),
    );
    

    Using app module

    ts
    // app.module.ts
    import { StatsigService } from '@statsig/angular-bindings';
    import { AppComponent } from './app.component';
    
    @NgModule({
      declarations: [AppComponent],
      imports: [],
      providers: [
        {
          provide: STATSIG_INIT_CONFIG,
          useValue: StatsigConfig,
        },
      ],
      bootstrap: [AppComponent],
    })
    export class AppModule {}
    

Use the SDK

After providing the Statsig config token, you can inject the service into a component or another service and use it.

ts
// example.component.ts
import { Component } from '@angular/core';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  selector: 'app-example',
  template: `...`,
})
export class ExampleComponent {
  constructor(private statsigService: StatsigService) {}
}

Checking a Feature Flag/Gate

After the SDK is initialized, check a Feature Gate. Feature Gates create logic branches in code that can be rolled out to different users from the Statsig Console. Gates are always CLOSED or OFF (equivalent to return false;) by default.
ts
// feature-gate.component.ts
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  standalone: true,
  selector: 'app-feature-gate',
  imports: [CommonModule],
  template: `<div *ngIf="isFeatureEnabled">Feature is enabled!</div>`,
})
export class FeatureGateComponent implements OnInit {
  isFeatureEnabled = false;

  constructor(private statsigService: StatsigService) {}

  ngOnInit(): void {
    this.isFeatureEnabled = this.statsigService.checkGate('feature_gate_name');
  }
}

Reading a Dynamic Config

Feature Gates work well for simple on/off switches with optional advanced user targeting. To send a different set of values (strings, numbers, and so on) to clients based on specific user attributes such as country, use Dynamic Configs. The API is similar to Feature Gates, but returns an entire JSON object you configure on the server, from which you can fetch typed parameters. For example:

ts
// dynamic-config.component.ts
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  standalone: true,
  selector: 'app-dynamic-config',
  imports: [CommonModule],
  template: `<div *ngIf="configValue">Config Value: {{ configValue }}</div>`,
})
export class DynamicConfigComponent implements OnInit {
  configValue: string | null = null;

  constructor(private statsigService: StatsigService) {}

  ngOnInit(): void {
    const dynamicConfig = this.statsigService.getDynamicConfig('config_name');
    this.configValue = dynamicConfig.get('key', 'default_value');
  }
}

Getting a Layer/Experiment

Layers/Experiments support running A/B/n experiments. Two APIs are available, but layers are recommended to enable quicker iterations with parameter reuse.
ts
// experiment.component.ts
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  standalone: true,
  selector: 'app-experiment',
  imports: [CommonModule],
  template: `<div *ngIf="experimentValue">Experiment Value: {{ experimentValue }}</div>`,
})
export class ExperimentComponent implements OnInit {
  experimentValue: string | null = null;

  constructor(private statsigService: StatsigService) {}

  ngOnInit(): void {
    const experiment = this.statsigService.getExperiment('experiment_name');
    this.experimentValue = experiment.get('experiment_key', 'default');
  }
}
ts
// layer.component.ts
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  standalone: true,
  selector: 'app-layer',
  imports: [CommonModule],
  template: `<div *ngIf="layerValue">Layer Value: {{ layerValue }}</div>`,
})
export class LayerComponent implements OnInit {
  layerValue: string | null = null;

  constructor(private statsigService: StatsigService) {}

  ngOnInit(): void {
    const layer = this.statsigService.getLayer('layer_name');
    this.layerValue = layer.get('layer_key', 'default_layer_value');
  }
}

Logging an Event

After setting up a Feature Gate or an Experiment, you can track custom events to see how your new features or different experiment groups affect those events. Call the Log Event API for the event, and optionally provide a value and metadata object to be logged with the event:

ts
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  standalone: true,
  selector: 'app-log-event',
  imports: [CommonModule],
  template: `
    <button (click)="logUserAction()">Click Me</button>
    <p *ngIf="message">{{ message }}</p>
  `,
})
export class LogEventComponent {
  message: string | null = null;

  constructor(private statsigService: StatsigService) {}

  logUserAction(): void {
    this.statsigService.logEvent('UserClickedButton', 1, {
      buttonColor: 'blue',
      buttonText: 'Click Me',
    });

    this.message = 'Event logged: UserClickedButton';
  }
}

Flushing logged events

flush() sends queued events immediately. Use shutdown() when your app is exiting.

ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  standalone: true,
  selector: 'app-flush-events',
  imports: [CommonModule],
  template: `
    <button (click)="flushEvents()">Flush Events</button>
    <p *ngIf="message">{{ message }}</p>
  `,
})
export class FlushEventsComponent {
  message: string | null = null;

  constructor(private statsigService: StatsigService) {}

  async flushEvents(): Promise<void> {
    await this.statsigService.getClient().flush();
    this.message = 'Queued events flushed';
  }
}

Updating user properties (e.g., Login)

Update user properties when the user logs in and a userID is assigned, or when new properties are identified. Statsig fetches new values for all gate, experiment, and config evaluations in response. Call updateUserAsync from the service:

ts
import { Component } from '@angular/core';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  selector: 'app-user-update',
  template: `
    <button (click)="updateUser()">Update User</button>
  `,
})
export class UserUpdateComponent {
  constructor(private statsigService: StatsigService) {}

  updateUser(): void {
    const user = {
      userID: 'user-1234',
      email: 'user@example.com',
      // Add other user properties here
    };

    this.statsigService.updateUserAsync(user)
      .then(() => {
        console.log('User updated successfully');
      })
      .catch((error) => {
        console.error('Error updating user:', error);
      });
  }
}

Loading State

Depending on your setup, you may want to wait for the latest values before checking a gate or experiment. Use the isLoading observable to determine whether the SDK is still loading and display a loading state accordingly.

ts
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { StatsigService } from '@statsig/angular-bindings';

@Component({
  selector: 'app-loading-state',
  imports: [CommonModule],
  template: `
    <div *ngIf="isLoading | async; else content">
      <p>Loading...</p>
    </div>
    <ng-template #content>
      <p>Content loaded successfully!</p>
    </ng-template>
  `,
})
export class LoadingStateComponent implements OnInit {
  isLoading = this.statsigService.isLoading$;

  constructor(private statsigService: StatsigService) {}

  ngOnInit(): void {
    // other initialization logic here
  }
}

Shutting Statsig Down

To save data and battery usage and prevent logged events from being dropped, the SDK keeps event logs in client cache and flushes them periodically. Because of this, some events may not have been sent when your app shuts down.

To ensure all logged events are flushed or saved locally, call shutdown when your app is closing:

ts
import { StatsigService } from '@statsig/angular-bindings';

export class ShutdownStatsigComponent {
  constructor(private statsigService: StatsigService) {}

  ngOnDestroy(): void {
    void this.statsigService.getClient().shutdown();
  }
}

Angular directives

Statsig Module

To use the directives, you need to import the StatsigModule in your Angular module.

ts
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { StatsigModule } from '@statsig/angular-bindings';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, StatsigModule],
  bootstrap: [AppComponent]
})
export class AppModule {}

Check gate directive

The stgCheckGate directive conditionally displays content in your Angular templates based on the evaluation of a Feature Gate from Statsig. It listens for updates to the feature gate's value and dynamically adds or removes content based on whether the gate is enabled.

ts
// feature-demo.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-feature-demo',
  template: `
    <div *stgCheckGate="'new_feature_gate'">
      <p>This content will only show if the 'new_feature_gate' is enabled.</p>
    </div>
  `,
})
export class FeatureDemoComponent {}

Session Replay

By including the @statsig/session-replay package in your project, you can automatically capture and log user sessions as videos. This is useful for debugging and understanding user behavior. Read more about Session Replay.
ts
import { STATSIG_INIT_CONFIG } from '@statsig/angular-bindings';
import { StatsigSessionReplayPlugin } from '@statsig/session-replay';

const StatsigConfig = {
        sdkKey: "client-KEY",
        user: { userID: 'a-user' },
        options: { plugins: [ new StatsigSessionReplayPlugin() ] }
}

Web analytics / auto capture

By including the @statsig/web-analytics package in your project, you can automatically capture common web events such as clicks and page views.For more information on filtering events, enabling console log capture, and other configuration options, refer to the Web Analytics Configuration documentation.
ts
import { STATSIG_INIT_CONFIG } from '@statsig/angular-bindings';
import { StatsigAutoCapturePlugin } from '@statsig/web-analytics';

const StatsigConfig = {
        sdkKey: "client-KEY",
        user: { userID: 'a-user' },
        options: { plugins: [ new StatsigAutoCapturePlugin() ] }
}

Was this helpful?