Claude Agent Skill · by Getsentry

Sentry React Sdk

Install Sentry React Sdk skill for Claude Code from getsentry/sentry-for-ai.

Install
Terminal · npx
$npx skills add https://github.com/vercel-labs/agent-skills --skill vercel-react-best-practices
Works with Paperclip

How Sentry React Sdk fits into a Paperclip company.

Sentry React Sdk drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md449 lines
Expand
---name: sentry-react-sdkdescription: 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, TanStack Router, Redux, Vite, and webpack.license: Apache-2.0category: sdk-setupparent: sentry-sdk-setupdisable-model-invocation: true--- > [All Skills](../../SKILL_TREE.md) > [SDK Setup](../sentry-sdk-setup/SKILL.md) > React SDK # Sentry React SDK Opinionated wizard that scans your React project and guides you through complete Sentry setup. ## Invoke This Skill When - User asks to "add Sentry to React" or "set up Sentry" in a React app- User wants error monitoring, tracing, session replay, profiling, or logging in React- User mentions `@sentry/react`, React Sentry SDK, or Sentry error boundaries- User wants to monitor React Router navigation, Redux state, or component performance > **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/](https://docs.sentry.io/platforms/javascript/guides/react/) before implementing. --- ## Phase 1: Detect Run these commands to understand the project before making any recommendations: ```bash# Detect React versioncat package.json | grep -E '"react"|"react-dom"' # Check for existing Sentrycat package.json | grep '"@sentry/' # Detect routercat package.json | grep -E '"react-router-dom"|"@tanstack/react-router"' # Detect state managementcat package.json | grep -E '"redux"|"@reduxjs/toolkit"' # Detect build toolls vite.config.ts vite.config.js webpack.config.js craco.config.js 2>/dev/nullcat package.json | grep -E '"vite"|"react-scripts"|"webpack"' # Detect logging librariescat package.json | grep -E '"pino"|"winston"|"loglevel"' # Check for companion backend in adjacent directoriesls ../backend ../server ../api 2>/dev/nullcat ../go.mod ../requirements.txt ../Gemfile ../pom.xml 2>/dev/null | head -3``` **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-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 | --- ## Phase 2: Recommend Present a concrete recommendation based on what you found. Don't ask open-ended questions — lead with a proposal: **Recommended (core coverage):**- ✅ **Error Monitoring** — always; captures unhandled errors, React error boundaries, React 19 hooks- ✅ **Tracing** — React SPAs benefit from page load, navigation, and API call tracing- ✅ **Session Replay** — recommended for user-facing apps; records sessions around errors **Optional (enhanced observability):**- ⚡ **Logging** — structured logs via `Sentry.logger.*`; recommend when structured log search is needed- ⚡ **Profiling** — JS Self-Profiling API (⚠️ experimental; requires cross-origin isolation headers) **Recommendation 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:**- React 19 detected → set up `reactErrorHandler()` on `createRoot`- React Router detected → configure matching router integration (see Phase 3)- Redux detected → add `createReduxEnhancer()` to Redux store- Vite detected → configure `sentryVitePlugin` 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?"* --- ## Phase 3: Guide ### Install ```bashnpm install @sentry/react --save``` ### Create `src/instrument.ts` Sentry must initialize **before any other code runs**. Put `Sentry.init()` in a dedicated sidecar file: ```typescriptimport * as Sentry from "@sentry/react"; Sentry.init({  dsn: import.meta.env.VITE_SENTRY_DSN, // Adjust per build tool (see table below)  environment: import.meta.env.MODE,  release: import.meta.env.VITE_APP_VERSION, // inject at build time   sendDefaultPii: true,   integrations: [    Sentry.browserTracingIntegration(),    Sentry.replayIntegration({      maskAllText: true,      blockAllMedia: true,    }),  ],   // Tracing  tracesSampleRate: 1.0, // lower to 0.1–0.2 in production  tracePropagationTargets: ["localhost", /^https:\/\/yourapi\.io/],   // Session Replay  replaysSessionSampleRate: 0.1,  replaysOnErrorSampleRate: 1.0,   enableLogs: true,});``` **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` | ### Entry Point Setup Import `instrument.ts` as the **very first import** in your entry file: ```tsx// src/main.tsx (Vite) or src/index.tsx (CRA/webpack)import "./instrument";              // ← MUST be first import { StrictMode } from "react";import { createRoot } from "react-dom/client";import App from "./App"; createRoot(document.getElementById("root")!).render(  <StrictMode>    <App />  </StrictMode>);``` ### React Version-Specific Error Handling **React 19+** — use `reactErrorHandler()` on `createRoot`: ```tsximport { reactErrorHandler } from "@sentry/react"; createRoot(document.getElementById("root")!, {  onUncaughtError: reactErrorHandler(),  onCaughtError: reactErrorHandler(),  onRecoverableError: reactErrorHandler(),}).render(<App />);``` **React <19** — wrap your app in `Sentry.ErrorBoundary`: ```tsximport * as Sentry from "@sentry/react"; createRoot(document.getElementById("root")!).render(  <Sentry.ErrorBoundary fallback={<p>Something went wrong</p>} showDialog>    <App />  </Sentry.ErrorBoundary>);``` Use `<Sentry.ErrorBoundary>` for any sub-tree that should catch errors independently (route sections, widgets, etc.). ### Router Integration Configure the matching integration for your router: | 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:** ```typescript// in instrument.ts integrations array:import React from "react";import {  createRoutesFromChildren, matchRoutes,  useLocation, useNavigationType,} from "react-router-dom"; // or "react-router" for v7import * as Sentry from "@sentry/react";import { reactRouterV6BrowserTracingIntegration } from "@sentry/react";import { createBrowserRouter } from "react-router-dom"; // Option A — createBrowserRouter (recommended for v6.4+):const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouterV6(createBrowserRouter);const router = sentryCreateBrowserRouter([...routes]); // Option B — createBrowserRouter for React Router v7:// const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouterV7(createBrowserRouter); // Option C — integration with hooks (v6 without data APIs):Sentry.init({  integrations: [    reactRouterV6BrowserTracingIntegration({      useEffect: React.useEffect,      useLocation,      useNavigationType,      matchRoutes,      createRoutesFromChildren,    }),  ],});``` **TanStack Router setup:** ```typescriptimport { tanstackRouterBrowserTracingIntegration } from "@sentry/react"; // Pass your TanStack router instance:Sentry.init({  integrations: [tanstackRouterBrowserTracingIntegration(router)],});``` ### Redux Integration (when detected) ```typescriptimport * as Sentry from "@sentry/react";import { configureStore } from "@reduxjs/toolkit"; const store = configureStore({  reducer: rootReducer,  enhancers: (getDefaultEnhancers) =>    getDefaultEnhancers().concat(Sentry.createReduxEnhancer()),});``` ### Source Maps Setup (strongly recommended) Without source maps, stack traces show minified code. Set up the build plugin to upload source maps automatically: **Vite (`vite.config.ts`):** ```typescriptimport { defineConfig } from "vite";import react from "@vitejs/plugin-react";import { sentryVitePlugin } from "@sentry/vite-plugin"; export default defineConfig({  build: { sourcemap: "hidden" },  plugins: [    react(),    sentryVitePlugin({      org: process.env.SENTRY_ORG,      project: process.env.SENTRY_PROJECT,      authToken: process.env.SENTRY_AUTH_TOKEN,    }),  ],});``` Add to `.env` (never commit):```bashSENTRY_AUTH_TOKEN=sntrys_...SENTRY_ORG=my-org-slugSENTRY_PROJECT=my-project-slug``` **Create React App (via CRACO):** ```bashnpm install @craco/craco @sentry/webpack-plugin --save-dev``` ```javascript// craco.config.jsconst { sentryWebpackPlugin } = require("@sentry/webpack-plugin"); module.exports = {  webpack: {    plugins: {      add: [        sentryWebpackPlugin({          org: process.env.SENTRY_ORG,          project: process.env.SENTRY_PROJECT,          authToken: process.env.SENTRY_AUTH_TOKEN,        }),      ],    },  },};``` ### For Each Agreed Feature 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. --- ## Configuration Reference ### Key `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 || `sendDefaultPii` | `boolean` | `false` | Includes IP addresses and request headers || `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 | ### React Compatibility Matrix | 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 | --- ## Verification Trigger test events to confirm Sentry is receiving data: ```tsx// Add a temporary test button anywhere in your appimport * as Sentry from "@sentry/react"; function SentryTest() {  return (    <>      <button onClick={() => { throw new Error("Sentry React test error"); }}>        Test Error      </button>      <button onClick={() => Sentry.captureMessage("Sentry test message", "info")}>        Test Message      </button>    </>  );}``` Check the Sentry dashboard:- **Issues** → error appears within seconds- **Traces** → page load and navigation transactions visible- **Replays** → session recording visible after page interaction- **Logs** → structured log entries if logging enabled Set `debug: true` in `Sentry.init()` and check the browser console if nothing appears. --- ## Phase 4: Cross-Link After completing React setup, check for a companion backend missing Sentry coverage: ```bashls ../backend ../server ../api ../go ../python 2>/dev/nullcat ../go.mod 2>/dev/null | head -3cat ../requirements.txt ../pyproject.toml 2>/dev/null | head -3cat ../Gemfile 2>/dev/null | head -3cat ../pom.xml 2>/dev/null | grep '<artifactId>' | head -3``` 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/](https://docs.sentry.io/platforms/java/) || Node.js (Express, Fastify) | Use `@sentry/node` — see [docs.sentry.io/platforms/javascript/guides/express/](https://docs.sentry.io/platforms/javascript/guides/express/) | --- ## Troubleshooting | 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 |