@arlioz/flagship-angular
v5.1.0
Published
Official Angular SDK for FlagShip — feature flags for startups
Maintainers
Readme
@arlioz/flagship-angular
Official Angular SDK for FlagShip — feature flags for startups.
Wraps the core @arlioz/flagship JavaScript SDK with Angular-native APIs: injectable service, structural directive, pipe, and Signal support.
Installation
npm install @arlioz/flagship @arlioz/flagship-angularQuick Start
Standalone Setup (Angular 19+, recommended)
// app.config.ts
import { provideFlagShip } from '@arlioz/flagship-angular'
export const appConfig: ApplicationConfig = {
providers: [
provideFlagShip({
apiKey: 'flg_production_...',
baseUrl: 'https://api.flagship.dev/api',
}),
],
}NgModule Setup
// app.module.ts
import { FlagShipModule } from '@arlioz/flagship-angular'
@NgModule({
imports: [
FlagShipModule.forRoot({
apiKey: 'flg_production_...',
baseUrl: 'https://api.flagship.dev/api',
}),
],
})
export class AppModule {}Usage
Signal API (recommended for Angular 19+)
import { Component, inject } from '@angular/core'
import { FlagShipService } from '@arlioz/flagship-angular'
@Component({
selector: 'app-feature',
template: `
@if (darkMode()) {
<div class="dark">Dark mode is enabled!</div>
}
<p>Welcome message: {{ welcomeMsg() }}</p>
`,
})
export class FeatureComponent {
private flagship = inject(FlagShipService)
darkMode = this.flagship.flag('dark-mode', false)
welcomeMsg = this.flagship.flag('welcome-message', 'Hello!')
}RxJS API
import { Component, inject } from '@angular/core'
import { AsyncPipe } from '@angular/common'
import { FlagShipService } from '@arlioz/flagship-angular'
@Component({
selector: 'app-feature',
imports: [AsyncPipe],
template: ` <div *ngIf="darkMode$ | async">Dark mode is enabled!</div> `,
})
export class FeatureComponent {
private flagship = inject(FlagShipService)
darkMode$ = this.flagship.getFlag('dark-mode', false)
}Structural Directive
import { Component } from '@angular/core'
import { IfFlagDirective } from '@arlioz/flagship-angular'
@Component({
selector: 'app-feature',
imports: [IfFlagDirective],
template: `
<div *ifFlag="'beta-feature'; else fallback">Welcome to the beta!</div>
<ng-template #fallback>
<p>This feature is coming soon.</p>
</ng-template>
`,
})
export class FeatureComponent {}Pipe
import { Component } from '@angular/core'
import { FlagValuePipe } from '@arlioz/flagship-angular'
@Component({
selector: 'app-feature',
imports: [FlagValuePipe],
template: ` <h1>{{ 'welcome-message' | flagValue: 'Hello, World!' }}</h1> `,
})
export class FeatureComponent {}Route Guard
Protect routes behind feature flags with flagGuard():
import { Routes } from '@angular/router'
import { flagGuard } from '@arlioz/flagship-angular'
const routes: Routes = [
{
path: 'beta-dashboard',
component: BetaDashboardComponent,
canActivate: [flagGuard('beta-dashboard')],
},
{
path: 'new-checkout',
component: NewCheckoutComponent,
canActivate: [flagGuard('new-checkout', '/checkout')], // redirect to /checkout if disabled
},
]User Targeting
import { Component, inject } from '@angular/core'
import { FlagShipService } from '@arlioz/flagship-angular'
@Component({
/* ... */
})
export class AppComponent {
private flagship = inject(FlagShipService)
async onLogin(user: { id: string; plan: string }) {
await this.flagship.identify(user.id, { plan: user.plan })
// Flags are now re-evaluated for this user
}
}API Reference
FlagShipService
| Method | Return | Description |
| --------------------------------------- | --------------------------------- | --------------------------------------- |
| getFlag<T>(key, defaultValue) | Observable<T> | Single flag value, emits only on change |
| getFlags() | Observable<Record<string, any>> | All flag values |
| flag<T>(key, defaultValue) | Signal<T> | Single flag as Angular Signal |
| flags() | Signal<Record<string, any>> | All flags as Angular Signal |
| getFlagSnapshot<T>(key, defaultValue) | T | Synchronous read from cache |
| identify(userId, attributes?) | Promise<void> | Update user context and re-fetch flags |
IfFlagDirective
Structural directive that shows/hides content based on a boolean flag.
<div *ifFlag="'flag-key'">Shown when flag is true</div>
<div *ifFlag="'flag-key'; else other">With else template</div>FlagValuePipe
Pipe that resolves a flag value in templates.
{{ 'flag-key' | flagValue:'default value' }}Configuration Options
| Option | Type | Default | Description |
| ----------------- | --------------------- | --------------------------- | ------------------------------------- |
| apiKey | string | required | Environment API key |
| baseUrl | string | http://localhost:4000/api | API base URL |
| userId | string | — | User ID for rollout targeting |
| attributes | Record<string, any> | {} | User attributes for targeting |
| pollingInterval | number | 30000 | Polling interval in ms (0 to disable) |
Compatibility
| Angular | Status | | ------- | --------------------------- | | 16.x | Supported (Signal API lazy) | | 17.x | Supported | | 18.x | Supported | | 19.x | Supported | | 20.x | Supported | | 21.x | Supported (latest) |
- Works with both standalone and NgModule patterns
- Compatible with zoneless change detection (Signal API)
- Compatible with OnPush change detection strategy
Angular 10–15? Use
@arlioz/flagship-angular-legacy— pure RxJS/NgModule, no Signals.
License
MIT
