Official AllStak SDK for Angular. Captures uncaught exceptions, structured logs, navigation spans, outbound HTTP requests, and component render timing — with first-class support for both standalone and NgModule-based apps.
npm install @allstak/angular
# or
pnpm add @allstak/angular
# or
yarn add @allstak/angular@angular/core, @angular/common, and rxjs are peer dependencies; @angular/router is an optional peer (only needed for navigation instrumentation).
Initialise the SDK once in main.ts, before you bootstrap the app, so the global error handler and router instrumentation see a live client:
import { init } from '@allstak/angular';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';
init({
apiKey: 'your-ingest-key',
environment: 'production',
});
bootstrapApplication(AppComponent, appConfig);Wire the DI pieces in app.config.ts:
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import {
provideAllStak,
provideAllStakErrorHandler,
provideAllStakRouterInstrumentation,
allStakHttpInterceptor,
} from '@allstak/angular';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
// Bootstrap the SDK from DI (alternative to calling init() in main.ts).
provideAllStak({ apiKey: 'your-ingest-key', environment: 'production' }),
// Override Angular's global ErrorHandler — every uncaught error becomes an Issue.
provideAllStakErrorHandler(),
// Open a navigation span per route change.
provideAllStakRouterInstrumentation(),
// Record every outbound HTTP request + open a http.client span.
provideHttpClient(withInterceptors([allStakHttpInterceptor])),
],
};import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { AllStakModule, AllStakHttpInterceptor } from '@allstak/angular';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
// forRoot() initialises the SDK, overrides ErrorHandler, force-instantiates
// the router TraceService, and exposes the [trace] directive.
AllStakModule.forRoot({ apiKey: 'your-ingest-key', environment: 'production' }),
],
providers: [
provideHttpClient(withInterceptorsFromDi()),
{ provide: HTTP_INTERCEPTORS, useClass: AllStakHttpInterceptor, multi: true },
],
bootstrap: [AppComponent],
})
export class AppModule {}createErrorHandler() returns an Angular ErrorHandler that forwards to AllStak.captureException. It unwraps the common Angular/zone.js error envelopes (ngOriginalError, promise rejection, HttpErrorResponse.error, ErrorEvent.error) before capture.
import { ErrorHandler } from '@angular/core';
import { createErrorHandler } from '@allstak/angular';
providers: [
{
provide: ErrorHandler,
useValue: createErrorHandler({
logErrors: true, // also console.error the original (default)
extractor: (error, defaultExtractor) =>
(error as { cause?: unknown }).cause ?? defaultExtractor(error),
}),
},
];TraceService subscribes to Angular Router events and opens a navigation span per route change (finishing ok on NavigationEnd, error on NavigationCancel / NavigationError), plus a navigation breadcrumb. It must be force-instantiated — provideAllStakRouterInstrumentation() (standalone) or AllStakModule.forRoot() (NgModule) does that for you.
The [trace] directive opens a ui.angular.init span between a component's ngOnInit and ngAfterViewInit. Import TraceDirective directly (standalone) or AllStakTraceModule (NgModule):
// standalone component
import { Component } from '@angular/core';
import { TraceDirective } from '@allstak/angular';
@Component({
standalone: true,
imports: [TraceDirective],
template: `<section trace="dashboard">…</section>`,
})
export class DashboardComponent {}You can also instrument classes/methods with the decorators (the name is required so spans survive minification):
import { TraceClassDecorator, TraceMethodDecorator } from '@allstak/angular';
@TraceClassDecorator({ name: 'CheckoutComponent' })
@Component({ /* … */ })
export class CheckoutComponent {
@TraceMethodDecorator({ name: 'CheckoutComponent.ngOnInit' })
ngOnInit() {}
}The interceptor records every outbound request as an outbound HTTP item and opens a http.client span around it (finished error on 4xx/5xx or transport failure). Use the functional allStakHttpInterceptor with withInterceptors([...]) or the class AllStakHttpInterceptor with HTTP_INTERCEPTORS. It never mutates the request.
init(config), provideAllStak(config), and AllStakModule.forRoot(config) all accept every option that @allstak/js's AllStak.init accepts. Common options:
| Option | Purpose |
|---|---|
apiKey |
Ingest key (required) |
host |
Override the ingest host |
environment |
e.g. 'production' / 'development' |
release |
Release identifier for issue grouping / release health |
tracesSampleRate |
Span sampling rate (0–1) |
enableWebVitals |
Capture web vitals |
enableAutoSessionTracking |
Release-health sessions |
enableOfflineQueue |
Buffer events while offline |
beforeSend |
Mutate/drop events before they are sent |
The full @allstak/js API is re-exported, so you can pull the entire observability surface from one import:
import * as AllStakAngular from '@allstak/angular';
AllStakAngular.AllStak.captureMessage('checkout started', 'info');
const span = AllStakAngular.AllStak.startSpan('checkout.flow', { description: 'review → pay' });
span.finish('ok');MIT