The @sentry/angular package provides error tracking and performance monitoring for Angular applications. It includes Angular-specific integrations like ErrorHandler, TraceService, and component tracking.
Prerequisites
- Node.js 18 or newer
- Angular 14 to 21
- RxJS 6.5.5+ or 7.x
- A Sentry account and project DSN
Angular versions 14-21 are officially supported. For older versions, check the compatibility table.
Installation
Install the Package
Install @sentry/angular using your preferred package manager:npm install @sentry/angular
Current Version: 10.42.0 Initialize Sentry
Initialize Sentry before you bootstrap your Angular application in main.ts:import { bootstrapApplication } from '@angular/platform-browser';
import { init } from '@sentry/angular';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';
init({
dsn: 'YOUR_DSN_HERE',
integrations: [
// Add Angular-specific integrations
],
// Tracing
tracesSampleRate: 1.0,
});
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
Configure Error Handler
Register the Sentry ErrorHandler provider in your app configuration:import { ApplicationConfig, ErrorHandler } from '@angular/core';
import { provideRouter } from '@angular/router';
import { createErrorHandler } from '@sentry/angular';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
{
provide: ErrorHandler,
useValue: createErrorHandler({
showDialog: true,
}),
},
],
};
For NgModule-based apps, add the provider to your AppModule instead.
Verify Installation
Test that Sentry is working:import * as Sentry from '@sentry/angular';
Sentry.captureException(new Error('Test error'));
Check your Sentry dashboard to see the error.
NgModule Configuration (Legacy)
For older Angular applications using NgModule:
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { createErrorHandler } from '@sentry/angular';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
{
provide: ErrorHandler,
useValue: createErrorHandler({
showDialog: true,
}),
},
],
bootstrap: [AppComponent],
})
export class AppModule {}
Error Handler Options
Customize the error handler behavior:
import { createErrorHandler } from '@sentry/angular';
export const appConfig: ApplicationConfig = {
providers: [
{
provide: ErrorHandler,
useValue: createErrorHandler({
// Show the user feedback dialog
showDialog: true,
// Configure dialog options
dialogOptions: {
title: 'It looks like we\'re having issues.',
subtitle: 'Our team has been notified.',
subtitle2: 'If you\'d like to help, tell us what happened below.',
user: {
email: '[email protected]',
name: 'John Doe',
},
},
// Log errors to console
logErrors: true,
}),
},
],
};
Basic Configuration
Enable Browser Tracing
Add the browser tracing integration:import { init, browserTracingIntegration } from '@sentry/angular';
init({
dsn: 'YOUR_DSN_HERE',
integrations: [
browserTracingIntegration(),
],
tracesSampleRate: 1.0,
tracePropagationTargets: ['localhost', 'https://yourserver.io/api'],
});
Initialize TraceService
Inject the TraceService in your app initialization to enable Angular Router tracking:import { ApplicationConfig, APP_INITIALIZER } from '@angular/core';
import { TraceService } from '@sentry/angular';
export const appConfig: ApplicationConfig = {
providers: [
{
provide: APP_INITIALIZER,
useFactory: () => () => {},
deps: [TraceService],
multi: true,
},
],
};
Angular 19+: Use provideAppInitializer:import { ApplicationConfig, provideAppInitializer, inject } from '@angular/core';
import { TraceService } from '@sentry/angular';
export const appConfig: ApplicationConfig = {
providers: [
provideAppInitializer(() => inject(TraceService)),
],
};
NgModule Configuration
For NgModule-based apps:
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { TraceService } from '@sentry/angular';
@NgModule({
providers: [
{
provide: APP_INITIALIZER,
useFactory: () => () => {},
deps: [TraceService],
multi: true,
},
],
})
export class AppModule {}
Component Tracking
Track Angular component performance with three different methods:
1. TraceDirective
Track component lifecycle in templates:
import { Component } from '@angular/core';
import { TraceModule } from '@sentry/angular';
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [TraceModule],
template: `
<app-header trace="header"></app-header>
<app-sidebar trace="sidebar"></app-sidebar>
<app-content trace="content"></app-content>
<app-footer trace="footer"></app-footer>
`,
})
export class DashboardComponent {}
The directive’s name attribute is required and will be used as the span name.
2. TraceClass Decorator
Track component lifecycle in component classes:
import { Component } from '@angular/core';
import { TraceClass } from '@sentry/angular';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
})
@TraceClass()
export class HeaderComponent {
// Component code
}
3. TraceMethod Decorator
Track specific lifecycle hooks:
import { Component, OnInit } from '@angular/core';
import { TraceMethod } from '@sentry/angular';
@Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
})
export class FooterComponent implements OnInit {
@TraceMethod()
ngOnInit() {
// Initialization code
}
@TraceMethod()
ngAfterViewInit() {
// After view initialization
}
}
Custom Spans
Create custom performance spans:
import { Component } from '@angular/core';
import { startSpan } from '@sentry/angular';
@Component({
selector: 'app-data',
templateUrl: './data.component.html',
})
export class DataComponent {
async loadData() {
const data = await startSpan(
{
name: 'fetch-user-data',
op: 'http.client',
},
async () => {
const response = await fetch('/api/user');
return response.json();
}
);
return data;
}
}
Tracking Application Bootstrap
Measure how long your Angular app takes to bootstrap:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { init, startSpan } from '@sentry/angular';
import { AppModule } from './app/app.module';
init({
dsn: 'YOUR_DSN_HERE',
integrations: [browserTracingIntegration()],
tracesSampleRate: 1.0,
});
startSpan(
{
name: 'platform-browser-dynamic',
op: 'ui.angular.bootstrap',
},
async () => {
await platformBrowserDynamic().bootstrapModule(AppModule);
}
);
Usage
Capturing Errors
import { Component } from '@angular/core';
import * as Sentry from '@sentry/angular';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
})
export class UserComponent {
async loadUser(id: string) {
try {
const response = await fetch(`/api/users/${id}`);
return response.json();
} catch (error) {
Sentry.captureException(error);
throw error;
}
}
}
Setting Context
import { Component, OnInit } from '@angular/core';
import * as Sentry from '@sentry/angular';
import { AuthService } from './auth.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
constructor(private auth: AuthService) {}
ngOnInit() {
this.auth.user$.subscribe(user => {
if (user) {
Sentry.setUser({
id: user.id,
email: user.email,
username: user.username,
});
} else {
Sentry.setUser(null);
}
});
// Set tags
Sentry.setTag('angular_version', '17.0.0');
// Set extra context
Sentry.setExtra('build_number', '12345');
}
}
Adding Breadcrumbs
import { Component } from '@angular/core';
import * as Sentry from '@sentry/angular';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
})
export class FormComponent {
onSubmit(formData: any) {
Sentry.addBreadcrumb({
category: 'form',
message: 'User submitted form',
level: 'info',
data: {
formId: 'contact-form',
fields: Object.keys(formData),
},
});
this.submitForm(formData);
}
}
HttpClient Integration
Automatically capture HTTP errors:
import { ApplicationConfig, provideHttpClient } from '@angular/core';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
// Sentry automatically instruments HttpClient
],
};
The SDK will automatically:
- Create spans for HTTP requests
- Capture HTTP errors
- Add breadcrumbs for requests
Session Replay
Capture session replays:
import { init, browserTracingIntegration, replayIntegration } from '@sentry/angular';
init({
dsn: 'YOUR_DSN_HERE',
integrations: [
browserTracingIntegration(),
replayIntegration({
maskAllText: true,
blockAllMedia: true,
}),
],
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
Advanced Configuration
TypeScript
The SDK is written in TypeScript and includes full type definitions:
import type { ErrorHandlerOptions } from '@sentry/angular';
const errorHandlerOptions: ErrorHandlerOptions = {
showDialog: true,
logErrors: true,
dialogOptions: {
title: 'An error occurred',
},
};
Custom Transport
import { init, makeBrowserOfflineTransport, makeFetchTransport } from '@sentry/angular';
init({
dsn: 'YOUR_DSN_HERE',
transport: makeBrowserOfflineTransport(makeFetchTransport),
});
Filtering Events
init({
dsn: 'YOUR_DSN_HERE',
beforeSend(event, hint) {
// Don't send errors from development
if (window.location.hostname === 'localhost') {
return null;
}
return event;
},
beforeBreadcrumb(breadcrumb, hint) {
// Don't record console breadcrumbs
if (breadcrumb.category === 'console') {
return null;
}
return breadcrumb;
},
});
Troubleshooting
Source Maps
For Angular CLI projects:
-
Install the Sentry Webpack plugin:
npm install @sentry/webpack-plugin --save-dev
-
Configure in
angular.json:
{
"projects": {
"your-app": {
"architect": {
"build": {
"options": {
"sourceMap": true
}
}
}
}
}
}
-
Add custom webpack config with
@angular-builders/custom-webpack
Zone.js Compatibility
Sentry is compatible with Zone.js. Make sure Zone.js is loaded before Sentry:
// polyfills.ts
import 'zone.js';
// main.ts
import { init } from '@sentry/angular';
// Zone.js is already loaded
Errors Not Captured
Make sure:
Sentry.init() is called before bootstrapping Angular
- The
ErrorHandler provider is registered
- The error is not caught without re-throwing
Initialize Sentry before calling bootstrapApplication() or platformBrowserDynamic().bootstrapModule().
Ensure:
browserTracingIntegration() is added
TraceService is injected via APP_INITIALIZER
tracesSampleRate is greater than 0
Next Steps