npx skills add ...
npx skills add getsentry/sentry-for-claude --skill sentry-react-sdk
Full Sentry SDK setup for React. Use when asked to "add Sentry to React", "install @sentry/react", or configure error monitoring, tracing, session replay, profiling, or logging for React applications. Supports React 16+, React Router v5-v7 non-framework mode, TanStack Router, Redux, Vite, and webpack.
This repo is now called getsentry/sentry-for-ai. Both names install the same content, but the install count here only covers this one.
npx skills add getsentry/sentry-for-claude --skill sentry-react-sdk
All Skills > SDK Setup > React SDK
Opinionated wizard that scans your React project and guides you through complete Sentry setup.
@sentry/react, React Sentry SDK, or Sentry error boundariesIf project is React Router Framework mode using @sentry/react-router, use sentry-react-router-framework-sdk instead of this skill.
Note: SDK versions and APIs below reflect current Sentry docs at time of writing (
@sentry/react≥8.0.0). Always verify against docs.sentry.io/platforms/javascript/guides/react/ before implementing.
Run these commands to understand the project before making any recommendations:
What to determine:
| Question | Impact |
|---|---|
| React 19+? | Use reactErrorHandler() hook pattern |
| React <19? | Use Sentry.ErrorBoundary |
@sentry/react already present? | Skip install, go straight to feature config |
React Router Framework mode indicators (@sentry/react-router, @react-router/*)? | Use sentry-react-router-framework-sdk |
react-router-dom v5 / v6 / v7? | Determines which router integration to use |
@tanstack/react-router? | Use tanstackRouterBrowserTracingIntegration() |
| Redux in use? | Recommend createReduxEnhancer() |
| Vite detected? | Source maps via sentryVitePlugin |
CRA (react-scripts)? | Source maps via @sentry/webpack-plugin in CRACO |
| Backend directory found? | Trigger Phase 4 cross-link suggestion |
Present a concrete recommendation based on what you found. Don't ask open-ended questions — lead with a proposal:
Recommended (core coverage):
Optional (enhanced observability):
Sentry.logger.*; recommend when structured log search is neededRecommendation logic:
| Feature | Recommend when... |
|---|---|
| Error Monitoring | Always — non-negotiable baseline |
| Tracing | Always for React SPAs — page load + navigation spans are high-value |
| Session Replay | User-facing app, login flows, or checkout pages |
| Logging | App needs structured log search or log-to-trace correlation |
| Profiling | Performance-critical app; server sends Document-Policy: js-profiling header |
React-specific extras:
reactErrorHandler() on createRootsentry-react-router-framework-sdkcreateReduxEnhancer() to Redux storesentryVitePlugin for source maps (essential for readable stack traces)Propose: "I recommend setting up Error Monitoring + Tracing + Session Replay. Want me to also add Logging or Profiling?"
src/instrument.tsSentry must initialize before any other code runs. Put Sentry.init() in a dedicated sidecar file:
DSN environment variable by build tool:
| Build Tool | Variable Name | Access in code |
|---|---|---|
| Vite | VITE_SENTRY_DSN | import.meta.env.VITE_SENTRY_DSN |
| Create React App | REACT_APP_SENTRY_DSN | process.env.REACT_APP_SENTRY_DSN |
| Custom webpack | SENTRY_DSN | process.env.SENTRY_DSN |
Import instrument.ts as the very first import in your entry file:
React 19+ — use reactErrorHandler() on createRoot:
React <19 — wrap your app in Sentry.ErrorBoundary:
Use <Sentry.ErrorBoundary> for any sub-tree that should catch errors independently (route sections, widgets, etc.).
Configure the matching integration for your router (non-framework mode):
| Router | Integration | Notes |
|---|---|---|
| React Router v7 | reactRouterV7BrowserTracingIntegration | useEffect, useLocation, useNavigationType, createRoutesFromChildren, matchRoutes from react-router |
| React Router v6 | reactRouterV6BrowserTracingIntegration | useEffect, useLocation, useNavigationType, createRoutesFromChildren, matchRoutes from react-router-dom |
| React Router v5 | reactRouterV5BrowserTracingIntegration | Wrap routes in withSentryRouting(Route) |
| TanStack Router | tanstackRouterBrowserTracingIntegration(router) | Pass router instance — no hooks required |
| No router / custom | browserTracingIntegration() | Names transactions by URL path |
React Router v6/v7 setup:
TanStack Router setup:
Without source maps, stack traces show minified code. Set up the build plugin to upload source maps automatically:
Vite (vite.config.ts):
Create React App (via CRACO):
SENTRY_ORG / SENTRY_PROJECT / SENTRY_AUTH_TOKEN are build-time values; the auth token is a secret (never commit it). For creating the token and wiring it into CI, see sentry-source-maps.
Walk through features one at a time. Load the reference file, follow its steps, verify before moving on:
| Feature | Reference | Load when... |
|---|---|---|
| Error Monitoring | ${SKILL_ROOT}/references/error-monitoring.md | Always (baseline) |
| Tracing | ${SKILL_ROOT}/references/tracing.md | SPA navigation / API call tracing |
| Session Replay | ${SKILL_ROOT}/references/session-replay.md | User-facing app |
| Logging | ${SKILL_ROOT}/references/logging.md | Structured log search / log-to-trace |
| Profiling | ${SKILL_ROOT}/references/profiling.md | Performance-critical app |
| React Features | ${SKILL_ROOT}/references/react-features.md | Redux, component tracking, source maps, integrations catalog |
For each feature: Read ${SKILL_ROOT}/references/<feature>.md, follow steps exactly, verify it works.
Sentry.init() Options| Option | Type | Default | Notes |
|---|---|---|---|
dsn | string | — | Required. SDK disabled when empty |
environment | string | "production" | e.g., "staging", "development" |
release | string | — | e.g., "my-app@1.0.0" or git SHA — links errors to releases |
dataCollection | object | conservative unless set | Fine-grained control over auto-collected categories (userInfo, cookies, httpHeaders, httpBodies, queryParams, genAI). When omitted, the SDK falls back to sendDefaultPii (default false). Passing the object — even {} — flips unset categories to their permissive defaults; opt out per category. |
tracesSampleRate | number | — | 0–1; 1.0 in dev, 0.1–0.2 in prod |
tracesSampler | function | — | Per-transaction sampling; overrides rate |
tracePropagationTargets | (string|RegExp)[] | — | Outgoing URLs that receive distributed tracing headers |
replaysSessionSampleRate | number | — | Fraction of all sessions recorded |
replaysOnErrorSampleRate | number | — | Fraction of error sessions recorded |
enableLogs | boolean | false | Enable Sentry.logger.* API |
attachStacktrace | boolean | false | Stack traces on captureMessage() calls |
maxBreadcrumbs | number | 100 | Breadcrumbs stored per event |
debug | boolean | false | Verbose SDK output to console |
tunnel | string | — | Proxy URL to bypass ad blockers |
dataCollection Options (SDK ≥10.57.0)Fine-grained control over what data the SDK collects. Collection is on by default (with sensitive-value scrubbing); opt out per category:
| Field | Type | Default | Notes |
|---|---|---|---|
userInfo | boolean | true | Collect user id, email, and IP |
cookies | boolean | { allow: string[] } | { deny: string[] } | true | Cookie collection and filtering; true = all cookies (sensitive keys filtered) |
httpHeaders.request | boolean | { allow: string[] } | { deny: string[] } | true | HTTP request header collection |
httpHeaders.response | boolean | { allow: string[] } | { deny: string[] } | true | HTTP response header collection |
queryParams | boolean | { allow: string[] } | { deny: string[] } | true | Query parameter collection and filtering |
httpBodies | HttpBodyCollectionTarget[] | ["incomingRequest", "outgoingRequest", "incomingResponse", "outgoingResponse"] | Collect request/response bodies; options: 'incomingRequest', 'outgoingRequest', 'incomingResponse', 'outgoingResponse' |
genAI.inputs | boolean | true | Record AI model inputs (for AI monitoring) |
genAI.outputs | boolean | true | Record AI model outputs (for AI monitoring) |
stackFrameVariables | boolean | true | Capture local variable values in stack frames |
frameContextLines | number | 5 | Source code context lines around stack frames |
Example: Allow only specific cookies and headers:
| React Version | Error handling approach | SDK minimum |
|---|---|---|
| React 19+ | reactErrorHandler() on createRoot | @sentry/react ≥8.0.0 |
| React 16–18 | Sentry.ErrorBoundary component | @sentry/react ≥7.0.0 |
| React 16 | componentDidCatch class boundaries | @sentry/react ≥6.0.0 |
Trigger test events to confirm Sentry is receiving data:
Check the Sentry dashboard:
Set debug: true in Sentry.init() and check the browser console if nothing appears.
After completing React setup, check for a companion backend missing Sentry coverage:
If a backend exists without Sentry configured, suggest the matching skill:
| Backend detected | Suggest skill |
|---|---|
Go (go.mod) | sentry-go-sdk |
Python (requirements.txt, pyproject.toml) | sentry-python-sdk |
Ruby (Gemfile) | sentry-ruby-sdk |
Java (pom.xml, build.gradle) | Use @sentry/java — see docs.sentry.io/platforms/java/ |
| Node.js (Express, Fastify) | Use @sentry/node — see docs.sentry.io/platforms/javascript/guides/express/ |
| Issue | Solution |
|---|---|
| Events not appearing | Set debug: true, check DSN, open browser console for SDK errors |
| Source maps not working | Build in production mode (npm run build); verify SENTRY_AUTH_TOKEN is set |
| Minified stack traces | Source maps not uploading — check plugin config and auth token |
instrument.ts not running first | Verify it's the first import in entry file before React/app imports |
| React 19 errors not captured | Confirm reactErrorHandler() is passed to all three createRoot options |
| React <19 errors not captured | Ensure <Sentry.ErrorBoundary> wraps the component tree |
Router transactions named <unknown> | Add router integration matching your router version |
tracePropagationTargets not matching | Check regex escaping; default is localhost and your DSN origin only |
| Session replay not recording | Confirm replayIntegration() is in init; check replaysSessionSampleRate |
| Redux actions not in breadcrumbs | Add Sentry.createReduxEnhancer() to store enhancers |
| Ad blockers dropping events | Set tunnel: "/sentry-tunnel" and add server-side relay endpoint |
| High replay storage costs | Lower replaysSessionSampleRate; keep replaysOnErrorSampleRate: 1.0 |
| Profiling not working | Verify Document-Policy: js-profiling header is set on document responses |