Skip to main content
The @sentry/react package provides error tracking, performance monitoring, and React-specific features like Error Boundaries and component profiling.

Prerequisites

  • Node.js 18 or newer
  • React 16.14.0, 17.x, 18.x, or 19.x
  • A Sentry account and project DSN

Installation

1

Install the Package

Install @sentry/react using your preferred package manager:
npm install @sentry/react
Current Version: 10.42.0
2

Initialize Sentry

Initialize Sentry before you mount your React component. This should be done as early as possible:
import React from 'react';
import { createRoot } from 'react-dom/client';
import * as Sentry from '@sentry/react';
import App from './App';

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.replayIntegration(),
  ],
  
  // Tracing
  tracesSampleRate: 1.0,
  
  // Session Replay
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
});

const container = document.getElementById('app');
const root = createRoot(container);
root.render(<App />);
3

Verify Installation

Test that Sentry is working:
Sentry.captureException(new Error('Test error'));
Check your Sentry dashboard to see the error.

React 19 Error Handling

Starting with React 19, createRoot and hydrateRoot expose error hooks that can be used to capture errors automatically:
import { createRoot } from 'react-dom/client';
import * as Sentry from '@sentry/react';
import App from './App';

const container = document.getElementById('app');
const root = createRoot(container, {
  // Callback called when an error is thrown and not caught by an Error Boundary
  onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
    console.warn('Uncaught error', error, errorInfo.componentStack);
  }),
  
  // Callback called when React catches an error in an Error Boundary
  onCaughtError: Sentry.reactErrorHandler(),
  
  // Callback called when React automatically recovers from errors
  onRecoverableError: Sentry.reactErrorHandler(),
});

root.render(<App />);
For finer-grained control, use only the onUncaughtError and onRecoverableError hooks, and use an ErrorBoundary component instead of the onCaughtError hook.

Error Boundary

The @sentry/react package exports an ErrorBoundary component that automatically captures JavaScript errors from inside a component tree and displays a fallback UI:
import React from 'react';
import * as Sentry from '@sentry/react';

function FallbackComponent() {
  return <div>An error has occurred</div>;
}

function App() {
  return (
    <Sentry.ErrorBoundary fallback={FallbackComponent} showDialog>
      <YourApplication />
    </Sentry.ErrorBoundary>
  );
}

export default App;

Error Boundary Options

<Sentry.ErrorBoundary
  fallback={FallbackComponent}
  showDialog={true}
  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.',
  }}
  beforeCapture={(scope, error, errorInfo) => {
    scope.setTag('location', 'boundary');
    scope.setContext('errorBoundary', errorInfo);
  }}
>
  <YourApplication />
</Sentry.ErrorBoundary>

Multiple Error Boundaries

You can use multiple error boundaries to isolate different parts of your app:
function App() {
  return (
    <Sentry.ErrorBoundary fallback={ErrorPage}>
      <Header />
      
      <Sentry.ErrorBoundary fallback={SidebarError}>
        <Sidebar />
      </Sentry.ErrorBoundary>
      
      <Sentry.ErrorBoundary fallback={ContentError}>
        <Content />
      </Sentry.ErrorBoundary>
      
      <Footer />
    </Sentry.ErrorBoundary>
  );
}

React Profiler

The Profiler component tracks component lifecycle performance:
import * as Sentry from '@sentry/react';

function App() {
  return (
    <div>
      <Sentry.Profiler name="Header">
        <Header />
      </Sentry.Profiler>
      
      <Sentry.Profiler name="MainContent">
        <MainContent />
      </Sentry.Profiler>
      
      <Sentry.Profiler name="Footer">
        <Footer />
      </Sentry.Profiler>
    </div>
  );
}
Or wrap an entire component with the HOC:
import * as Sentry from '@sentry/react';

class MyComponent extends React.Component {
  render() {
    return (
      <div>
        <Header />
        <Content />
        <Footer />
      </div>
    );
  }
}

export default Sentry.withProfiler(MyComponent);
The Profiler requires tracing to be enabled. If tracing is not enabled, the Profiler will not work.

React Router Integration

React Router v6

import React from 'react';
import {
  createBrowserRouter,
  RouterProvider,
} from 'react-router-dom';
import * as Sentry from '@sentry/react';

const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouter(
  createBrowserRouter
);

const router = sentryCreateBrowserRouter([
  {
    path: '/',
    element: <Home />,
  },
  {
    path: '/about',
    element: <About />,
  },
]);

function App() {
  return <RouterProvider router={router} />;
}

React Router v5 and v4

import React from 'react';
import { Router, Route, Switch } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import * as Sentry from '@sentry/react';

const history = createBrowserHistory();

const SentryRoutes = Sentry.withSentryRouting(Route);

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  integrations: [
    Sentry.browserTracingIntegration({ routingInstrumentation: Sentry.reactRouterV5Instrumentation(history) }),
  ],
  tracesSampleRate: 1.0,
});

function App() {
  return (
    <Router history={history}>
      <Switch>
        <SentryRoutes path="/" component={Home} exact />
        <SentryRoutes path="/about" component={About} />
      </Switch>
    </Router>
  );
}

Usage

Capturing Errors

import * as Sentry from '@sentry/react';

try {
  someFunctionThatMightFail();
} catch (error) {
  Sentry.captureException(error);
}

Setting Context

import * as Sentry from '@sentry/react';

// Set user information
Sentry.setUser({ 
  id: '123',
  email: '[email protected]',
  username: 'john_doe' 
});

// Set tags
Sentry.setTag('page', 'profile');

// Set extra context
Sentry.setExtra('userData', userData);

Adding Breadcrumbs

import * as Sentry from '@sentry/react';

Sentry.addBreadcrumb({
  category: 'ui.click',
  message: 'User clicked on submit button',
  level: 'info',
});

Custom Spans

import * as Sentry from '@sentry/react';

function MyComponent() {
  const fetchData = async () => {
    const data = await Sentry.startSpan(
      { name: 'fetch-user-data', op: 'http.client' },
      async () => {
        const response = await fetch('/api/user');
        return response.json();
      }
    );
    
    return data;
  };
  
  // ...
}

Performance Monitoring

Basic Configuration

import * as Sentry from '@sentry/react';

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  integrations: [
    Sentry.browserTracingIntegration(),
  ],
  
  tracesSampleRate: 1.0,
  tracePropagationTargets: ['localhost', /^https:\/\/yourserver\.io\/api/],
});

With React Router

import * as Sentry from '@sentry/react';
import { useEffect } from 'react';
import { useLocation, useNavigationType, createRoutesFromChildren, matchRoutes } from 'react-router-dom';

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  integrations: [
    Sentry.reactRouterV6BrowserTracingIntegration({
      useEffect,
      useLocation,
      useNavigationType,
      createRoutesFromChildren,
      matchRoutes,
    }),
  ],
  
  tracesSampleRate: 1.0,
});

Session Replay

Capture session replays to see what users experienced:
import * as Sentry from '@sentry/react';

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  integrations: [
    Sentry.replayIntegration({
      maskAllText: true,
      blockAllMedia: true,
    }),
  ],
  
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
});

Privacy Options

Sentry.replayIntegration({
  // Mask all text content
  maskAllText: true,
  
  // Block all media elements (video, audio, img)
  blockAllMedia: true,
  
  // Mask specific elements by CSS selector
  mask: ['.sensitive-data', '#credit-card'],
  
  // Block specific elements
  block: ['.ads', '.third-party-widget'],
})

Advanced Configuration

TypeScript

The SDK is written in TypeScript and includes type definitions:
import * as Sentry from '@sentry/react';
import type { ErrorBoundaryProps } from '@sentry/react';

const errorBoundaryConfig: ErrorBoundaryProps = {
  fallback: ({ error, componentStack, resetError }) => (
    <div>
      <h1>An error occurred</h1>
      <p>{error.message}</p>
      <button onClick={resetError}>Try again</button>
    </div>
  ),
  showDialog: true,
};

Redux Integration

import { configureStore } from '@reduxjs/toolkit';
import * as Sentry from '@sentry/react';

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  actionTransformer: (action) => {
    if (action.type === 'SENSITIVE_ACTION') {
      return null; // Don't send this action to Sentry
    }
    return action;
  },
});

const store = configureStore({
  reducer: rootReducer,
  enhancers: [sentryReduxEnhancer],
});

Next Steps After Errors

import * as Sentry from '@sentry/react';

function ErrorFallback({ error, componentStack, resetError }) {
  const eventId = Sentry.lastEventId();
  
  return (
    <div>
      <h1>An error occurred</h1>
      <p>{error.message}</p>
      
      <button onClick={() => Sentry.showReportDialog({ eventId })}>
        Report feedback
      </button>
      
      <button onClick={resetError}>
        Try again
      </button>
    </div>
  );
}

Troubleshooting

Source Maps

For production builds with Webpack:
  1. Install the Webpack plugin:
    npm install @sentry/webpack-plugin --save-dev
    
  2. Configure in webpack.config.js:
    const { sentryWebpackPlugin } = require('@sentry/webpack-plugin');
    
    module.exports = {
      devtool: 'source-map',
      plugins: [
        sentryWebpackPlugin({
          authToken: process.env.SENTRY_AUTH_TOKEN,
          org: 'your-org',
          project: 'your-project',
        }),
      ],
    };
    
For Vite:
// vite.config.js
import { sentryVitePlugin } from '@sentry/vite-plugin';

export default defineConfig({
  build: {
    sourcemap: true,
  },
  plugins: [
    sentryVitePlugin({
      authToken: process.env.SENTRY_AUTH_TOKEN,
      org: 'your-org',
      project: 'your-project',
    }),
  ],
});

Error Boundaries Not Working

Make sure:
  1. You’re using a class component or the Sentry ErrorBoundary
  2. The error is thrown during render, not in event handlers
  3. For event handler errors, use try/catch with Sentry.captureException()
Error Boundaries do not catch errors in:
  • Event handlers (use try/catch instead)
  • Asynchronous code (setTimeout, promises)
  • Server-side rendering
  • Errors thrown in the Error Boundary itself

Next Steps

Build docs developers (and LLMs) love