tracekit-angular-sdk
TraceKit Angular SDK Setup
When To Use
Use this skill when the user asks to:
- Add TraceKit to an Angular application
- Add observability, error tracking, or APM to an Angular project
- Instrument an Angular app with distributed tracing
- Set up error monitoring in an Angular SPA
- Configure TraceKit in an Angular project with NgModule or standalone components
- Debug production Angular applications with live breakpoints
If the user has a vanilla JavaScript/TypeScript project without Angular, use the tracekit-browser-sdk skill instead.
Non-Negotiable Rules
- Never hardcode API keys in code. Always use Angular environment files with
TRACEKIT_API_KEYenv var injection. - Always include a verification step confirming errors appear in
https://app.tracekit.dev. - Always enable code monitoring (
enableCodeMonitoring: true) -- it is TraceKit's differentiator. - Always initialize TraceKit before app bootstrap -- the SDK must load before the application starts to capture all errors.
Detection
Before applying this skill, detect the project type:
- Check
package.jsonfor@angular/corein dependencies -- confirms this is an Angular project. - Detect architecture by scanning
src/main.ts:bootstrapModule(AppModule)=> NgModule architecture (use NgModule branch)bootstrapApplication(AppComponent)=> Standalone component architecture (use Standalone branch)
- Only ask the user if
main.tsis missing or uses an unrecognized bootstrap pattern.
Step 1: Environment Setup
Set the TRACEKIT_API_KEY environment variable. Angular uses environment files for configuration.
Add to src/environments/environment.ts (development):
export const environment = {
production: false,
tracekitApiKey: 'ctxio_your_dev_api_key_here',
};
Add to src/environments/environment.prod.ts (production):
export const environment = {
production: true,
tracekitApiKey: process.env['TRACEKIT_API_KEY'] || '',
};
Where to get your API key:
- Log in to TraceKit
- Go to API Keys page
- Generate a new key (starts with
ctxio_)
Do not commit real API keys. For production builds, inject TRACEKIT_API_KEY via your CI/CD pipeline or deployment environment.
Step 2: Install SDK
npm install @tracekit/angular
Or with Yarn:
yarn add @tracekit/angular
This installs the TraceKit Angular wrapper with the @tracekit/browser SDK, ErrorHandler integration, router breadcrumbs, and HttpClient interceptor for distributed tracing.
Step 3: Initialize TraceKit
Choose the branch matching your Angular architecture. Apply one of the following.
Branch A: Standalone Components (Angular 15+)
In src/main.ts:
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideTraceKit, provideTraceKitRouter } from '@tracekit/angular';
import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';
import { environment } from './environments/environment';
bootstrapApplication(AppComponent, {
providers: [
...provideTraceKit({
apiKey: environment.tracekitApiKey,
release: '1.0.0',
environment: environment.production ? 'production' : 'development',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
}),
provideRouter(routes),
...provideTraceKitRouter(),
provideHttpClient(),
],
});
provideTraceKit() initializes the SDK and returns a Provider[] array that replaces Angular's default ErrorHandler with TraceKitErrorHandler. Use the spread operator to merge into your providers array.
provideTraceKitRouter() sets up router breadcrumbs via APP_INITIALIZER. The router is lazily resolved from Angular's injector to avoid circular dependency issues.
Branch B: NgModule
In src/app/app.module.ts:
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { TraceKitModule } from '@tracekit/angular';
import { AppComponent } from './app.component';
import { HomeComponent } from './home.component';
import { UsersComponent } from './users.component';
import { environment } from '../environments/environment';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'users/:id', component: UsersComponent },
];
@NgModule({
declarations: [AppComponent, HomeComponent, UsersComponent],
imports: [
BrowserModule,
HttpClientModule,
RouterModule.forRoot(routes),
TraceKitModule.forRoot({
apiKey: environment.tracekitApiKey,
release: '1.0.0',
environment: environment.production ? 'production' : 'development',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}
TraceKitModule.forRoot() returns a module with providers that initializes the SDK, replaces the default ErrorHandler, and sets up router breadcrumbs. Do not mix TraceKitModule.forRoot() with provideTraceKit() in the same application.
Step 4: Error Handler
TraceKit replaces Angular's built-in ErrorHandler with TraceKitErrorHandler. This is done automatically by both provideTraceKit() (standalone) and TraceKitModule.forRoot() (NgModule).
The TraceKitErrorHandler class:
- Captures all unhandled errors via
captureException() - Extracts the original error from Angular wrappers (
error.originalErrorfor template errors,error.rejectionfor unhandled promise rejections) - Preserves Angular's default
console.erroroutput - Is registered via
{ provide: ErrorHandler, useClass: TraceKitErrorHandler }-- no@Injectable()decorator needed
Manual registration (only if you need to customize provider ordering):
Standalone:
import { ErrorHandler } from '@angular/core';
import { TraceKitErrorHandler } from '@tracekit/angular';
bootstrapApplication(AppComponent, {
providers: [
{ provide: ErrorHandler, useClass: TraceKitErrorHandler },
],
});
NgModule:
@NgModule({
providers: [
{ provide: ErrorHandler, useClass: TraceKitErrorHandler },
],
})
export class AppModule {}
Step 5: Router Integration
Navigation breadcrumbs are captured automatically via Angular Router events.
Standalone: Add ...provideTraceKitRouter() to your providers array (shown in Step 3).
NgModule: Router integration is included in TraceKitModule.forRoot() automatically.
The router integration subscribes to router.events and captures NavigationEnd events as breadcrumbs with from/to paths.
To disable parameterized routes (use actual URLs instead of route patterns):
// Standalone
...provideTraceKitRouter(false)
// NgModule
TraceKitModule.forRoot({
...config,
parameterizedRoutes: false,
})
Step 6: Custom Error Capture and Performance Spans
Import TraceKit functions directly from @tracekit/angular -- no dependency injection needed for the SDK functions:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { captureException, setUser } from '@tracekit/angular';
@Component({
selector: 'app-user',
template: '<h1>{{ user?.name }}</h1>',
})
export class UserComponent implements OnInit {
user: any;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
this.loadUser(id!);
}
async loadUser(id: string) {
try {
const res = await fetch('/api/users/' + id);
this.user = await res.json();
setUser({ id: this.user.id, email: this.user.email });
} catch (err) {
captureException(err as Error, { userId: id });
}
}
}
Re-exported functions available from @tracekit/angular:
import {
captureException,
captureMessage,
setUser,
setTag,
setExtra,
addBreadcrumb,
getClient,
} from '@tracekit/angular';
Step 7: Distributed Tracing
Add the TraceKit HttpClient interceptor to propagate trace headers to your backend APIs:
Standalone:
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { traceKitInterceptor } from '@tracekit/angular';
bootstrapApplication(AppComponent, {
providers: [
...provideTraceKit({
apiKey: environment.tracekitApiKey,
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
tracePropagationTargets: ['https://api.example.com', /^\/api\//],
}),
provideHttpClient(withInterceptors([traceKitInterceptor])),
],
});
NgModule:
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TraceKitHttpInterceptor } from '@tracekit/angular';
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: TraceKitHttpInterceptor,
multi: true,
},
],
})
export class AppModule {}
The tracePropagationTargets config option controls which outgoing requests receive trace headers. Set it to match your API domains.
Step 8: Session Replay (Optional)
Enable session replay to record and replay user sessions linked to error traces:
...provideTraceKit({
apiKey: environment.tracekitApiKey,
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
replay: {
enabled: true,
sampleRate: 0.1, // Record 10% of sessions
errorSampleRate: 1.0, // Record 100% of sessions with errors
maskAllText: true, // Mask sensitive text by default
blockAllMedia: false,
},
})
Session replay runs client-side only and captures DOM mutations, network requests, and console logs.
Step 9: Source Maps (Optional)
Upload source maps for readable stack traces in production errors.
Add to your angular.json build configuration:
{
"projects": {
"my-app": {
"architect": {
"build": {
"configurations": {
"production": {
"sourceMap": true
}
}
}
}
}
}
}
After building, upload source maps:
tracekit sourcemaps upload \
--api-key $TRACEKIT_API_KEY \
--release 1.0.0 \
--dist ./dist/my-app/browser
Add this command to your CI/CD pipeline after ng build --configuration production.
Step 10: Verification
After integrating, verify errors are captured:
- Start your application with
ng serveor deploy to a test environment. - Trigger a test error -- add a temporary button that throws:
throwTestError() { throw new Error('TraceKit Angular test error'); } - Open
https://app.tracekit.dev. - Confirm the test error appears within 30-60 seconds with component stack trace.
If errors do not appear, see Troubleshooting below.
Complete Working Example
Standalone Application (Angular 15+)
// src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import {
provideTraceKit,
provideTraceKitRouter,
traceKitInterceptor,
} from '@tracekit/angular';
import { AppComponent } from './app/app.component';
import { environment } from './environments/environment';
const routes = [
{ path: '', loadComponent: () => import('./app/home.component') },
{ path: 'users/:id', loadComponent: () => import('./app/user.component') },
];
bootstrapApplication(AppComponent, {
providers: [
...provideTraceKit({
apiKey: environment.tracekitApiKey,
release: '1.0.0',
environment: environment.production ? 'production' : 'development',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
tracePropagationTargets: ['https://api.example.com', /^\/api\//],
replay: {
enabled: true,
sampleRate: 0.1,
errorSampleRate: 1.0,
},
}),
provideRouter(routes),
...provideTraceKitRouter(),
provideHttpClient(withInterceptors([traceKitInterceptor])),
],
});
NgModule Application
// src/app/app.module.ts
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { TraceKitModule, TraceKitHttpInterceptor } from '@tracekit/angular';
import { AppComponent } from './app.component';
import { HomeComponent } from './home.component';
import { UsersComponent } from './users.component';
import { environment } from '../environments/environment';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'users/:id', component: UsersComponent },
];
@NgModule({
declarations: [AppComponent, HomeComponent, UsersComponent],
imports: [
BrowserModule,
HttpClientModule,
RouterModule.forRoot(routes),
TraceKitModule.forRoot({
apiKey: environment.tracekitApiKey,
release: '1.0.0',
environment: environment.production ? 'production' : 'development',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
tracePropagationTargets: ['https://api.example.com', /^\/api\//],
replay: {
enabled: true,
sampleRate: 0.1,
errorSampleRate: 1.0,
},
}),
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: TraceKitHttpInterceptor,
multi: true,
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
Troubleshooting
Errors not captured
- Check ErrorHandler provider ordering: If another library overrides
ErrorHandlerafter TraceKit, TraceKit's handler will not receive errors. EnsureprovideTraceKit()orTraceKitModule.forRoot()is listed before other provider overrides. - Check API key: Ensure
environment.tracekitApiKeyis set. Print it:console.log(environment.tracekitApiKey). - Check outbound access: Your app must reach
https://app.tracekit.dev/v1/traces. Test with:curl -X POST https://app.tracekit.dev/v1/traces(expect 401 -- means endpoint is reachable).
NgModule vs standalone confusion
- Detect via
src/main.ts: Look forbootstrapModule(AppModule)(NgModule) vsbootstrapApplication(AppComponent)(standalone). - Do not mix: Never use both
TraceKitModule.forRoot()andprovideTraceKit()in the same app.
Zone.js interactions
- TraceKit hooks into Angular's error handling via
ErrorHandler, which is zone-aware. The SDK does not patch Zone.js directly. - If using
zonelessmode (Angular 18+), TraceKit still works via theErrorHandlerDI token.
AOT compilation issues
TraceKitErrorHandleris a plain class without@Injectable()decorator, so it works with AOT compilation out of the box.- If you see "No provider for ErrorHandler" errors, ensure the TraceKit providers are in the root module/application config.
HttpClient interceptor not adding trace headers
- Verify
tracePropagationTargetsincludes your API domain. - Standalone: ensure
withInterceptors([traceKitInterceptor])is passed toprovideHttpClient(). - NgModule: ensure
HTTP_INTERCEPTORSprovider is registered withmulti: true.
Next Steps
Once your Angular app is traced, consider:
- Browser SDK -- For non-Angular pages in the same project, use the
tracekit-browser-sdkskill - Session Replay -- Record and replay user sessions with linked traces
- Source Maps -- Upload source maps for readable production stack traces
- Backend SDKs -- Connect frontend traces to backend services for full distributed tracing
References
- Angular SDK docs:
https://app.tracekit.dev/docs/frontend/frameworks/angular - Browser SDK docs:
https://app.tracekit.dev/docs/frontend/browser-sdk - TraceKit docs root:
https://app.tracekit.dev/docs - Dashboard:
https://app.tracekit.dev