Setting Up Sentry for React Apps: Step-by-Step
Setting up Sentry for React takes fewer than five minutes and requires only a Sentry account, an npm install, and a configuration block. Sentry is an error tracking platform that captures unhandled exceptions, promise rejections, and browser crashes in real time. Once configured, it automatically sends every error to a dashboard where you can group them, see stack traces, and set up alerts.
Creating a Sentry Project and Getting Your DSN
Start by creating a free account at https://sentry.io. Click "Projects" and select "Create Project." Choose React as the platform and either "Alert me on every new error" or "Never" (you can configure alerts later). Sentry will generate a unique Data Source Name (DSN): a URL that looks like https://[email protected]/7891011. This DSN is public—it is meant to be embedded in your browser code—and you will use it to initialize the SDK.
Copy your DSN to a safe location. In a React app using environment variables (recommended), save it as REACT_APP_SENTRY_DSN in a .env file:
REACT_APP_SENTRY_DSN=https://[email protected]/7891011
REACT_APP_ENVIRONMENT=production
For a Create React App (CRA) project, you must prefix it with REACT_APP_ so it is bundled into the client. For Vite, use VITE_ instead.
Installing the Sentry SDK
Install the Sentry React package and the browser tracing integration:
npm install @sentry/react @sentry/tracing
Or with Yarn:
yarn add @sentry/react @sentry/tracing
This adds approximately 30 KB to your bundle (gzipped). You will also need @sentry/cli to upload source maps:
npm install --save-dev @sentry/cli
Initializing Sentry in Your App
Open your main entry point (usually index.jsx or main.jsx in Vite) and initialize Sentry before rendering your app. This ensures Sentry hooks into the global error handler before any React code runs:
import React from "react";
import ReactDOM from "react-dom/client";
import * as Sentry from "@sentry/react";
import { BrowserTracing } from "@sentry/tracing";
import App from "./App";
Sentry.init({
dsn: process.env.REACT_APP_SENTRY_DSN,
environment: process.env.REACT_APP_ENVIRONMENT || "development",
integrations: [
new BrowserTracing({
routingInstrumentation: Sentry.reactRouterV6Instrumentation(
window.history
),
}),
new Sentry.Replay({
maskAllText: true,
blockAllMedia: true,
}),
],
tracesSampleRate: 0.1, // 10% of transactions for sampling
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0, // 100% on error for debugging
});
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Key configuration options explained:
dsn: Your Sentry project's public DSN. Leave blank to disable (useful for local development).environment: Tag errors as "production," "staging," or "development." Helpful for filtering on the dashboard.integrations: BrowserTracing captures navigation and fetch spans; Replay records a video-like replay of user actions for debugging.tracesSampleRate: A float between 0 and 1. Setting it to 0.1 means Sentry will send 10% of normal transactions (not error transactions, which are always sent). This balances detail with cost.replaysSessionSampleRate: The percentage of user sessions to record. Set to 0.1 in production to reduce replay storage costs.replaysOnErrorSampleRate: Always set to 1.0; whenever an error occurs, attach the replay to it.
Verifying the Setup
To test that Sentry is working, trigger an intentional error in your app. Add a button that throws an error:
function TestErrorButton() {
const handleClick = () => {
throw new Error("This is a test error from Sentry setup.");
};
return (
button onClick={handleClick}>Test Error</button>
);
}
export default TestErrorButton;
Click the button, then check your Sentry dashboard. Within 10 seconds, you should see the error appear under "Issues." The event will show:
- The error message and stack trace (likely minified at this stage).
- The browser and device.
- Breadcrumbs (user actions before the error).
- Session replay (if enabled).
If the error does not appear, check:
- DSN is set: Open your browser's Network tab and look for a POST request to
sentry.io. If it is missing, your DSN is probably empty or null. - Environment is correct: Sentry filters out errors from
developmentby default. Setenvironment: 'production'in development for testing. - Network is allowed: Some corporate networks or ad blockers block Sentry. Try disabling them temporarily.
Uploading Source Maps for Readable Stack Traces
When you build your React app for production, the bundle is minified and source maps are generated. Sentry receives stack traces from minified code by default, which is unreadable. To see your original TypeScript or JSX in stack traces, you must upload source maps to Sentry during the build process.
Create a Sentry configuration file in your project root called sentry.properties:
[auth]
token=your-sentry-auth-token
[defaults]
org=your-org-name
project=your-project-name
url=https://sentry.io/
Generate an auth token at https://sentry.io/settings/auth-tokens/. Then add a build script to your package.json:
{
"scripts": {
"build": "react-scripts build && sentry-cli releases files upload-sourcemaps ./build"
}
}
When you run npm run build, the Sentry CLI will:
- Build your React app and create source maps.
- Upload the source maps to Sentry under the current version.
- Delete local source maps (optional, for security).
After upload, any future errors from that release will show readable stack traces with line numbers and original code. This is invaluable for debugging production issues.
Wrapping Components with Error Boundaries
While Sentry captures unhandled errors automatically, you should still wrap error-prone components with Sentry's error boundary to provide a fallback UI. More details in the next article, but a quick example:
import * as Sentry from "@sentry/react";
const ErrorFallback = ({ error, resetError }) => (
div>
Sorry, something went wrong.
button onClick={resetError}>Try again</button>
/div>
);
const WrappedComponent = Sentry.withErrorBoundary(MyComponent, {
fallback: ErrorFallback,
});
This ensures users see a friendly message instead of a broken page, while Sentry still captures the error on the backend.
Key Takeaways
- Sentry setup takes five minutes: create a project, copy the DSN, install the SDK, and initialize in your entry point.
- Set
tracesSampleRateto 0.1 (10%) to balance detail with cost; errors are always sent regardless of sampling. - Upload source maps after every build so stack traces point to your original source code, not minified code.
- Enable session replay in production to see user actions before an error occurred.
- Test the setup with a throw-error button to verify events appear on the Sentry dashboard.
Frequently Asked Questions
Should I initialize Sentry before or after creating the React root?
Always initialize Sentry before rendering your app. Sentry needs to hook the global error and unhandledrejection events before any user code runs. Initializing after React renders will miss early errors.
What does tracesSampleRate do?
It controls the percentage of normal transactions (non-error requests) sent to Sentry. Setting it to 0.1 means 10% are sent, reducing costs. Errors are always sent at 100%, regardless of sampling. Start with 0.1 and adjust based on your traffic and Sentry quota.
Do source maps include my original code?
No. Source maps are compiled artifacts that map minified code back to original source lines. They do not include the full source code—only enough information for a debugger to show line numbers and variable names. This is secure for production.
Can I disable Sentry in development?
Yes. Set environment: 'development' and add a filter in the Sentry dashboard to exclude development errors. Or, in your config, check process.env.NODE_ENV and skip Sentry.init entirely if it is development.
What is the performance cost of Sentry?
The SDK is approximately 30 KB gzipped and adds 1–2 ms to page load time. Session replay adds 50–100 KB and a few milliseconds more. The async error reporting does not block your JavaScript. For most apps, this is negligible compared to the value of production monitoring.