@danieljvdm/dev-kit 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/README.md +6 -6
  2. package/package.json +1 -1
  3. package/skill-sources.jsonc +2 -33
  4. package/skill-sources.lock.json +15 -117
  5. package/skills/animate/LICENSE +21 -0
  6. package/skills/animate/NOTICE +10 -0
  7. package/skills/animate/SKILL.md +34 -0
  8. package/skills/animate/references/gestures.md +27 -0
  9. package/skills/animate/references/glossary.md +136 -0
  10. package/skills/animate/references/implementation.md +22 -0
  11. package/skills/animate/references/opportunities.md +18 -0
  12. package/skills/animate/references/principles.md +48 -0
  13. package/skills/animate/references/review.md +19 -0
  14. package/skills/cloudflare-workers/LICENSE +202 -0
  15. package/skills/cloudflare-workers/NOTICE +9 -0
  16. package/skills/cloudflare-workers/SKILL.md +26 -0
  17. package/skills/cloudflare-workers/references/durable-objects.md +68 -0
  18. package/skills/cloudflare-workers/references/sandbox.md +48 -0
  19. package/skills/cloudflare-workers/references/workers.md +63 -0
  20. package/skills/cloudflare-workers/references/wrangler.md +56 -0
  21. package/skills/design-ui/LICENSE +21 -0
  22. package/skills/design-ui/NOTICE +8 -0
  23. package/skills/design-ui/SKILL.md +29 -0
  24. package/skills/design-ui/references/appearance.md +22 -0
  25. package/skills/design-ui/references/components.md +33 -0
  26. package/skills/design-ui/references/exploration.md +50 -0
  27. package/skills/design-ui/references/libraries.md +39 -0
  28. package/skills/design-ui/references/themes.md +23 -0
  29. package/skills/dev-kit/SKILL.md +19 -38
  30. package/skills/dev-kit/references/cloudflare-worker-api.md +1 -1
  31. package/skills/dev-kit/references/skills.md +2 -2
  32. package/skills/effect-development/SKILL.md +27 -0
  33. package/skills/effect-development/agents/openai.yaml +4 -0
  34. package/skills/effect-development/references/api/index.md +32 -0
  35. package/skills/effect-development/references/api/schema-codecs.md +15 -0
  36. package/skills/{build-effect-apis/references → effect-development/references/api}/verification.md +10 -5
  37. package/skills/{effect-architecture-audit/SKILL.md → effect-development/references/architecture/index.md} +1 -6
  38. package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-client.md +8 -6
  39. package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-testing.md +7 -2
  40. package/skills/effect-development/references/atom/index.md +40 -0
  41. package/skills/{build-effect-clis/references → effect-development/references/cli}/entrypoints-and-testing.md +6 -2
  42. package/skills/effect-development/references/cli/index.md +39 -0
  43. package/skills/effect-development/references/setup.md +15 -0
  44. package/skills/open-pull-request/SKILL.md +10 -70
  45. package/skills/open-pull-request/references/evidence.md +22 -0
  46. package/skills/open-pull-request/references/explanation.md +21 -0
  47. package/skills/open-pull-request/references/publication.md +21 -0
  48. package/skills/sentry/LICENSE +202 -0
  49. package/skills/sentry/LICENSE-UPSTREAM +21 -0
  50. package/skills/sentry/NOTICE +14 -0
  51. package/skills/sentry/SKILL.md +33 -0
  52. package/skills/sentry/references/alert-payloads.md +105 -0
  53. package/skills/sentry/references/alerts.md +17 -0
  54. package/skills/sentry/references/artifacts.md +25 -0
  55. package/skills/sentry/references/auth-token.md +65 -0
  56. package/skills/sentry/references/concepts/ai-monitoring.md +131 -0
  57. package/skills/sentry/references/concepts/choosing-a-signal.md +78 -0
  58. package/skills/sentry/references/concepts/crons.md +50 -0
  59. package/skills/sentry/references/concepts/data-scrubbing.md +43 -0
  60. package/skills/sentry/references/concepts/errors.md +40 -0
  61. package/skills/sentry/references/concepts/logging.md +85 -0
  62. package/skills/sentry/references/concepts/metrics.md +49 -0
  63. package/skills/sentry/references/concepts/monitors.md +78 -0
  64. package/skills/sentry/references/concepts/profiling.md +38 -0
  65. package/skills/sentry/references/concepts/reduce-volume.md +49 -0
  66. package/skills/sentry/references/concepts/releases.md +43 -0
  67. package/skills/sentry/references/concepts/session-replay.md +35 -0
  68. package/skills/sentry/references/concepts/tracing.md +54 -0
  69. package/skills/sentry/references/concepts/user-feedback.md +36 -0
  70. package/skills/sentry/references/debug-artifacts/android.md +68 -0
  71. package/skills/sentry/references/debug-artifacts/apple.md +96 -0
  72. package/skills/sentry/references/debug-artifacts/dotnet.md +70 -0
  73. package/skills/sentry/references/debug-artifacts/flutter.md +65 -0
  74. package/skills/sentry/references/debug-artifacts/index.md +75 -0
  75. package/skills/sentry/references/debug-artifacts/javascript.md +94 -0
  76. package/skills/sentry/references/debug-artifacts/matching.md +73 -0
  77. package/skills/sentry/references/debug-artifacts/react-native.md +75 -0
  78. package/skills/sentry/references/first-error-setup.md +25 -0
  79. package/skills/sentry/references/instrumentation.md +30 -0
  80. package/skills/sentry/references/issues.md +32 -0
  81. package/skills/sentry/references/new-project.md +17 -0
  82. package/skills/sentry/references/otel-exporter.md +30 -0
  83. package/skills/sentry/references/release-workflow.md +31 -0
  84. package/skills/sentry/references/releases/ci-pipeline.md +214 -0
  85. package/skills/sentry/references/releases/index.md +93 -0
  86. package/skills/sentry/references/releases/suspect-commits.md +155 -0
  87. package/skills/sentry/references/releases/tagging.md +131 -0
  88. package/skills/sentry/references/releases/troubleshooting.md +67 -0
  89. package/skills/sentry/references/sdks/android/crons.md +305 -0
  90. package/skills/sentry/references/sdks/android/error-monitoring.md +800 -0
  91. package/skills/sentry/references/sdks/android/index.md +748 -0
  92. package/skills/sentry/references/sdks/android/integrations.md +48 -0
  93. package/skills/sentry/references/sdks/android/logging.md +374 -0
  94. package/skills/sentry/references/sdks/android/metrics.md +288 -0
  95. package/skills/sentry/references/sdks/android/profiling.md +397 -0
  96. package/skills/sentry/references/sdks/android/session-replay.md +406 -0
  97. package/skills/sentry/references/sdks/android/tracing.md +861 -0
  98. package/skills/sentry/references/sdks/browser/error-monitoring.md +861 -0
  99. package/skills/sentry/references/sdks/browser/index.md +714 -0
  100. package/skills/sentry/references/sdks/browser/logging.md +315 -0
  101. package/skills/sentry/references/sdks/browser/profiling.md +236 -0
  102. package/skills/sentry/references/sdks/browser/session-replay.md +586 -0
  103. package/skills/sentry/references/sdks/browser/tracing.md +561 -0
  104. package/skills/sentry/references/sdks/browser/user-feedback.md +354 -0
  105. package/skills/sentry/references/sdks/cloudflare/ai-monitoring.md +661 -0
  106. package/skills/sentry/references/sdks/cloudflare/crons.md +231 -0
  107. package/skills/sentry/references/sdks/cloudflare/durable-objects.md +381 -0
  108. package/skills/sentry/references/sdks/cloudflare/error-monitoring.md +329 -0
  109. package/skills/sentry/references/sdks/cloudflare/index.md +698 -0
  110. package/skills/sentry/references/sdks/cloudflare/logging.md +169 -0
  111. package/skills/sentry/references/sdks/cloudflare/nodejs-compat.md +134 -0
  112. package/skills/sentry/references/sdks/cloudflare/tracing.md +475 -0
  113. package/skills/sentry/references/sdks/cocoa/error-monitoring.md +394 -0
  114. package/skills/sentry/references/sdks/cocoa/index.md +497 -0
  115. package/skills/sentry/references/sdks/cocoa/logging.md +209 -0
  116. package/skills/sentry/references/sdks/cocoa/metrics.md +136 -0
  117. package/skills/sentry/references/sdks/cocoa/profiling.md +223 -0
  118. package/skills/sentry/references/sdks/cocoa/session-replay.md +257 -0
  119. package/skills/sentry/references/sdks/cocoa/tracing.md +524 -0
  120. package/skills/sentry/references/sdks/cocoa/user-feedback.md +310 -0
  121. package/skills/sentry/references/sdks/dotnet/crons.md +465 -0
  122. package/skills/sentry/references/sdks/dotnet/error-monitoring.md +1100 -0
  123. package/skills/sentry/references/sdks/dotnet/index.md +614 -0
  124. package/skills/sentry/references/sdks/dotnet/logging.md +556 -0
  125. package/skills/sentry/references/sdks/dotnet/metrics.md +229 -0
  126. package/skills/sentry/references/sdks/dotnet/profiling.md +296 -0
  127. package/skills/sentry/references/sdks/dotnet/tracing.md +897 -0
  128. package/skills/sentry/references/sdks/elixir/crons.md +371 -0
  129. package/skills/sentry/references/sdks/elixir/error-monitoring.md +335 -0
  130. package/skills/sentry/references/sdks/elixir/index.md +383 -0
  131. package/skills/sentry/references/sdks/elixir/logging.md +239 -0
  132. package/skills/sentry/references/sdks/elixir/tracing.md +233 -0
  133. package/skills/sentry/references/sdks/flutter/ecosystem-integrations.md +70 -0
  134. package/skills/sentry/references/sdks/flutter/error-monitoring.md +312 -0
  135. package/skills/sentry/references/sdks/flutter/index.md +728 -0
  136. package/skills/sentry/references/sdks/flutter/logging.md +387 -0
  137. package/skills/sentry/references/sdks/flutter/metrics.md +310 -0
  138. package/skills/sentry/references/sdks/flutter/profiling.md +214 -0
  139. package/skills/sentry/references/sdks/flutter/session-replay.md +308 -0
  140. package/skills/sentry/references/sdks/flutter/tracing.md +502 -0
  141. package/skills/sentry/references/sdks/go/crons.md +270 -0
  142. package/skills/sentry/references/sdks/go/error-monitoring.md +361 -0
  143. package/skills/sentry/references/sdks/go/index.md +324 -0
  144. package/skills/sentry/references/sdks/go/logging.md +354 -0
  145. package/skills/sentry/references/sdks/go/metrics.md +273 -0
  146. package/skills/sentry/references/sdks/go/profiling.md +46 -0
  147. package/skills/sentry/references/sdks/go/tracing.md +366 -0
  148. package/skills/sentry/references/sdks/index.md +41 -0
  149. package/skills/sentry/references/sdks/nestjs/ai-monitoring.md +410 -0
  150. package/skills/sentry/references/sdks/nestjs/crons.md +268 -0
  151. package/skills/sentry/references/sdks/nestjs/error-monitoring.md +729 -0
  152. package/skills/sentry/references/sdks/nestjs/index.md +699 -0
  153. package/skills/sentry/references/sdks/nestjs/logging.md +174 -0
  154. package/skills/sentry/references/sdks/nestjs/metrics.md +243 -0
  155. package/skills/sentry/references/sdks/nestjs/profiling.md +127 -0
  156. package/skills/sentry/references/sdks/nestjs/tracing.md +762 -0
  157. package/skills/sentry/references/sdks/nextjs/ai-monitoring.md +494 -0
  158. package/skills/sentry/references/sdks/nextjs/crons.md +383 -0
  159. package/skills/sentry/references/sdks/nextjs/error-monitoring.md +974 -0
  160. package/skills/sentry/references/sdks/nextjs/index.md +491 -0
  161. package/skills/sentry/references/sdks/nextjs/logging.md +381 -0
  162. package/skills/sentry/references/sdks/nextjs/metrics.md +411 -0
  163. package/skills/sentry/references/sdks/nextjs/profiling.md +403 -0
  164. package/skills/sentry/references/sdks/nextjs/session-replay.md +462 -0
  165. package/skills/sentry/references/sdks/nextjs/tracing.md +628 -0
  166. package/skills/sentry/references/sdks/node/ai-monitoring.md +303 -0
  167. package/skills/sentry/references/sdks/node/crons.md +432 -0
  168. package/skills/sentry/references/sdks/node/error-monitoring.md +1125 -0
  169. package/skills/sentry/references/sdks/node/index.md +942 -0
  170. package/skills/sentry/references/sdks/node/logging.md +380 -0
  171. package/skills/sentry/references/sdks/node/metrics.md +278 -0
  172. package/skills/sentry/references/sdks/node/profiling.md +373 -0
  173. package/skills/sentry/references/sdks/node/tracing.md +878 -0
  174. package/skills/sentry/references/sdks/php/ai-monitoring.md +310 -0
  175. package/skills/sentry/references/sdks/php/crons.md +265 -0
  176. package/skills/sentry/references/sdks/php/error-monitoring.md +626 -0
  177. package/skills/sentry/references/sdks/php/index.md +362 -0
  178. package/skills/sentry/references/sdks/php/laravel.md +542 -0
  179. package/skills/sentry/references/sdks/php/logging.md +242 -0
  180. package/skills/sentry/references/sdks/php/metrics.md +193 -0
  181. package/skills/sentry/references/sdks/php/profiling.md +115 -0
  182. package/skills/sentry/references/sdks/php/symfony.md +552 -0
  183. package/skills/sentry/references/sdks/php/tracing.md +516 -0
  184. package/skills/sentry/references/sdks/python/ai-monitoring.md +351 -0
  185. package/skills/sentry/references/sdks/python/crons.md +218 -0
  186. package/skills/sentry/references/sdks/python/error-monitoring.md +292 -0
  187. package/skills/sentry/references/sdks/python/index.md +361 -0
  188. package/skills/sentry/references/sdks/python/logging.md +234 -0
  189. package/skills/sentry/references/sdks/python/metrics.md +154 -0
  190. package/skills/sentry/references/sdks/python/profiling.md +120 -0
  191. package/skills/sentry/references/sdks/python/tracing.md +364 -0
  192. package/skills/sentry/references/sdks/react/error-monitoring.md +1607 -0
  193. package/skills/sentry/references/sdks/react/index.md +492 -0
  194. package/skills/sentry/references/sdks/react/logging.md +364 -0
  195. package/skills/sentry/references/sdks/react/profiling.md +322 -0
  196. package/skills/sentry/references/sdks/react/react-features.md +1272 -0
  197. package/skills/sentry/references/sdks/react/session-replay.md +1193 -0
  198. package/skills/sentry/references/sdks/react/tracing.md +1415 -0
  199. package/skills/sentry/references/sdks/react-native/error-monitoring.md +1481 -0
  200. package/skills/sentry/references/sdks/react-native/expo-config-plugin.md +45 -0
  201. package/skills/sentry/references/sdks/react-native/index.md +1030 -0
  202. package/skills/sentry/references/sdks/react-native/logging.md +444 -0
  203. package/skills/sentry/references/sdks/react-native/profiling.md +386 -0
  204. package/skills/sentry/references/sdks/react-native/session-replay.md +704 -0
  205. package/skills/sentry/references/sdks/react-native/tracing.md +1086 -0
  206. package/skills/sentry/references/sdks/react-native/user-feedback.md +815 -0
  207. package/skills/sentry/references/sdks/react-router-framework/error-monitoring.md +127 -0
  208. package/skills/sentry/references/sdks/react-router-framework/index.md +411 -0
  209. package/skills/sentry/references/sdks/react-router-framework/logging.md +66 -0
  210. package/skills/sentry/references/sdks/react-router-framework/profiling.md +57 -0
  211. package/skills/sentry/references/sdks/react-router-framework/react-router-framework-features.md +110 -0
  212. package/skills/sentry/references/sdks/react-router-framework/session-replay.md +67 -0
  213. package/skills/sentry/references/sdks/react-router-framework/tracing.md +96 -0
  214. package/skills/sentry/references/sdks/react-router-framework/user-feedback.md +71 -0
  215. package/skills/sentry/references/sdks/ruby/crons.md +184 -0
  216. package/skills/sentry/references/sdks/ruby/error-monitoring.md +248 -0
  217. package/skills/sentry/references/sdks/ruby/index.md +297 -0
  218. package/skills/sentry/references/sdks/ruby/logging.md +168 -0
  219. package/skills/sentry/references/sdks/ruby/metrics.md +196 -0
  220. package/skills/sentry/references/sdks/ruby/migration.md +321 -0
  221. package/skills/sentry/references/sdks/ruby/profiling.md +107 -0
  222. package/skills/sentry/references/sdks/ruby/tracing.md +388 -0
  223. package/skills/sentry/references/sdks/svelte/error-monitoring.md +456 -0
  224. package/skills/sentry/references/sdks/svelte/index.md +467 -0
  225. package/skills/sentry/references/sdks/svelte/logging.md +344 -0
  226. package/skills/sentry/references/sdks/svelte/session-replay.md +369 -0
  227. package/skills/sentry/references/sdks/svelte/tracing.md +406 -0
  228. package/skills/sentry/references/sdks/tanstack-start/error-monitoring.md +149 -0
  229. package/skills/sentry/references/sdks/tanstack-start/index.md +381 -0
  230. package/skills/sentry/references/sdks/tanstack-start/logging.md +74 -0
  231. package/skills/sentry/references/sdks/tanstack-start/session-replay.md +76 -0
  232. package/skills/sentry/references/sdks/tanstack-start/tanstackstart-features.md +128 -0
  233. package/skills/sentry/references/sdks/tanstack-start/tracing.md +123 -0
  234. package/skills/sentry/references/sdks/tanstack-start/user-feedback.md +81 -0
  235. package/skills/sentry/references/search-query-language.md +226 -0
  236. package/skills/sentry/references/semantics/angular.md +7 -0
  237. package/skills/sentry/references/semantics/app.md +28 -0
  238. package/skills/sentry/references/semantics/art.md +17 -0
  239. package/skills/sentry/references/semantics/aws.md +43 -0
  240. package/skills/sentry/references/semantics/browser.md +34 -0
  241. package/skills/sentry/references/semantics/cache.md +12 -0
  242. package/skills/sentry/references/semantics/client.md +8 -0
  243. package/skills/sentry/references/semantics/cloud.md +12 -0
  244. package/skills/sentry/references/semantics/cloudflare.md +23 -0
  245. package/skills/sentry/references/semantics/code.md +11 -0
  246. package/skills/sentry/references/semantics/culture.md +11 -0
  247. package/skills/sentry/references/semantics/db.md +21 -0
  248. package/skills/sentry/references/semantics/device.md +43 -0
  249. package/skills/sentry/references/semantics/error.md +7 -0
  250. package/skills/sentry/references/semantics/event.md +8 -0
  251. package/skills/sentry/references/semantics/exception.md +10 -0
  252. package/skills/sentry/references/semantics/faas.md +19 -0
  253. package/skills/sentry/references/semantics/file.md +8 -0
  254. package/skills/sentry/references/semantics/flag.md +7 -0
  255. package/skills/sentry/references/semantics/gcp.md +16 -0
  256. package/skills/sentry/references/semantics/gen_ai.md +53 -0
  257. package/skills/sentry/references/semantics/general.md +11 -0
  258. package/skills/sentry/references/semantics/graphql.md +9 -0
  259. package/skills/sentry/references/semantics/grpc.md +19 -0
  260. package/skills/sentry/references/semantics/http.md +34 -0
  261. package/skills/sentry/references/semantics/index.md +63 -0
  262. package/skills/sentry/references/semantics/jsonrpc.md +8 -0
  263. package/skills/sentry/references/semantics/jvm.md +12 -0
  264. package/skills/sentry/references/semantics/koa.md +7 -0
  265. package/skills/sentry/references/semantics/logger.md +7 -0
  266. package/skills/sentry/references/semantics/mcp.md +37 -0
  267. package/skills/sentry/references/semantics/mdc.md +7 -0
  268. package/skills/sentry/references/semantics/messaging.md +23 -0
  269. package/skills/sentry/references/semantics/middleware.md +7 -0
  270. package/skills/sentry/references/semantics/navigation.md +9 -0
  271. package/skills/sentry/references/semantics/nel.md +11 -0
  272. package/skills/sentry/references/semantics/network.md +17 -0
  273. package/skills/sentry/references/semantics/os.md +15 -0
  274. package/skills/sentry/references/semantics/otel.md +10 -0
  275. package/skills/sentry/references/semantics/params.md +7 -0
  276. package/skills/sentry/references/semantics/process.md +14 -0
  277. package/skills/sentry/references/semantics/react.md +7 -0
  278. package/skills/sentry/references/semantics/remix.md +7 -0
  279. package/skills/sentry/references/semantics/resource.md +7 -0
  280. package/skills/sentry/references/semantics/rpc.md +10 -0
  281. package/skills/sentry/references/semantics/score.md +10 -0
  282. package/skills/sentry/references/semantics/sentry.md +69 -0
  283. package/skills/sentry/references/semantics/server.md +8 -0
  284. package/skills/sentry/references/semantics/service.md +8 -0
  285. package/skills/sentry/references/semantics/session.md +7 -0
  286. package/skills/sentry/references/semantics/state.md +7 -0
  287. package/skills/sentry/references/semantics/thread.md +8 -0
  288. package/skills/sentry/references/semantics/timber.md +7 -0
  289. package/skills/sentry/references/semantics/trpc.md +8 -0
  290. package/skills/sentry/references/semantics/ui.md +18 -0
  291. package/skills/sentry/references/semantics/url.md +15 -0
  292. package/skills/sentry/references/semantics/user.md +17 -0
  293. package/skills/sentry/references/semantics/user_agent.md +7 -0
  294. package/skills/sentry/references/semantics/vercel.md +42 -0
  295. package/skills/sentry/references/setup-verification.md +39 -0
  296. package/skills/sentry/references/snapshots/github-actions-fanout.md +206 -0
  297. package/skills/sentry/references/snapshots/github-actions-simple.md +102 -0
  298. package/skills/sentry/references/snapshots/github-actions-swift-snapshot-testing.md +118 -0
  299. package/skills/sentry/references/snapshots/index.md +19 -0
  300. package/skills/sentry/references/snapshots/snapshot-previews.md +100 -0
  301. package/skills/sentry/references/snapshots/snapshots.md +123 -0
  302. package/skills/sentry/references/snapshots/wizard-setup.md +134 -0
  303. package/skills/testing/LICENSE +21 -0
  304. package/skills/testing/NOTICE +7 -0
  305. package/skills/testing/SKILL.md +13 -19
  306. package/skills/testing/agents/openai.yaml +1 -2
  307. package/skills/testing/references/selection.md +23 -0
  308. package/skills/testing/references/tdd.md +19 -0
  309. package/skills/testing/references/test-design.md +17 -0
  310. package/src/catalog.ts +1 -7
  311. package/skills/build-effect-apis/SKILL.md +0 -81
  312. package/skills/build-effect-apis/agents/openai.yaml +0 -4
  313. package/skills/build-effect-clis/SKILL.md +0 -92
  314. package/skills/build-effect-clis/agents/openai.yaml +0 -4
  315. package/skills/effect-architecture-audit/agents/openai.yaml +0 -4
  316. package/skills/effect-atom-state/SKILL.md +0 -97
  317. package/skills/effect-atom-state/agents/openai.yaml +0 -4
  318. package/skills/effect-ts/SKILL.md +0 -35
  319. package/skills/effect-ts/agents/openai.yaml +0 -4
  320. /package/skills/{build-effect-apis/references → effect-development/references/api}/cloudflare-workers.md +0 -0
  321. /package/skills/{build-effect-apis/references → effect-development/references/api}/runtime-assembly.md +0 -0
  322. /package/skills/{build-effect-apis/references → effect-development/references/api}/server-and-middleware.md +0 -0
  323. /package/skills/{build-effect-apis/references → effect-development/references/api}/shared-contracts.md +0 -0
  324. /package/skills/{effect-architecture-audit/references → effect-development/references/architecture}/service-and-boundary-audit.md +0 -0
  325. /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-lifecycle.md +0 -0
  326. /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-workflows.md +0 -0
  327. /package/skills/{effect-atom-state/references → effect-development/references/atom}/tanstack-start.md +0 -0
  328. /package/skills/{build-effect-clis/references → effect-development/references/cli}/command-design.md +0 -0
  329. /package/skills/{build-effect-clis/references → effect-development/references/cli}/processes-and-platform.md +0 -0
@@ -0,0 +1,1272 @@
1
+ # React-Specific Features — Sentry React SDK
2
+
3
+ > Minimum SDK: `@sentry/react` v8.0.0+
4
+
5
+ This is the catch-all deep dive for React-specific Sentry features: Redux integration,
6
+ component tracking, source maps, and the full integrations catalog.
7
+
8
+ ---
9
+
10
+ ## Table of Contents
11
+
12
+ 1. [Redux Integration](#1-redux-integration)
13
+ 2. [Component Tracking & Performance](#2-component-tracking--performance)
14
+ 3. [Source Maps](#3-source-maps)
15
+ 4. [Default Integrations](#4-default-integrations)
16
+ 5. [Optional Integrations](#5-optional-integrations)
17
+ 6. [Build Tool Detection & Environment Variables](#6-build-tool-detection--environment-variables)
18
+
19
+ ---
20
+
21
+ ## 1. Redux Integration
22
+
23
+ `Sentry.createReduxEnhancer()` hooks into your Redux store to automatically:
24
+
25
+ - Capture **Redux actions as breadcrumbs** on every Sentry error event
26
+ - Attach the **Redux state as a `redux_state.json` file** to error events
27
+ - Keep **Sentry scope tags in sync** with your Redux state
28
+
29
+ ### Setup — Redux Toolkit (`configureStore`)
30
+
31
+ ```typescript
32
+ import * as Sentry from "@sentry/react";
33
+ import { configureStore } from "@reduxjs/toolkit";
34
+ import rootReducer from "./reducers";
35
+
36
+ const sentryReduxEnhancer = Sentry.createReduxEnhancer({
37
+ // options — see below
38
+ });
39
+
40
+ const store = configureStore({
41
+ reducer: rootReducer,
42
+ enhancers: (getDefaultEnhancers) => {
43
+ return getDefaultEnhancers().concat(sentryReduxEnhancer);
44
+ },
45
+ });
46
+
47
+ export type RootState = ReturnType<typeof store.getState>;
48
+ export type AppDispatch = typeof store.dispatch;
49
+ export default store;
50
+ ```
51
+
52
+ > ⚠️ **Critical:** `sentryReduxEnhancer` is a **store enhancer**, not Redux middleware.
53
+ > Do **NOT** pass it inside `applyMiddleware()`.
54
+
55
+ ### Setup — Legacy `createStore` with Middleware
56
+
57
+ ```javascript
58
+ import { createStore, applyMiddleware, compose } from "redux";
59
+ import thunk from "redux-thunk";
60
+ import * as Sentry from "@sentry/react";
61
+
62
+ const sentryReduxEnhancer = Sentry.createReduxEnhancer();
63
+
64
+ const store = createStore(rootReducer, compose(applyMiddleware(thunk), sentryReduxEnhancer));
65
+ ```
66
+
67
+ ---
68
+
69
+ ### Options: `actionTransformer` — Filter/Scrub Actions Before Breadcrumbs
70
+
71
+ Called for every dispatched action.
72
+ Return the action to include it as a breadcrumb, a modified copy to scrub sensitive
73
+ fields, or `null` to drop it entirely.
74
+
75
+ ```typescript
76
+ const sentryReduxEnhancer = Sentry.createReduxEnhancer({
77
+ actionTransformer: (action) => {
78
+ // Drop high-volume or sensitive actions entirely
79
+ if (action.type === "WEBSOCKET_PING") return null;
80
+ if (action.type === "FETCH_SECRETS") return null;
81
+
82
+ // Scrub sensitive fields from certain actions
83
+ if (action.type === "USER_LOGIN") {
84
+ return {
85
+ ...action,
86
+ password: "[REDACTED]",
87
+ token: "[REDACTED]",
88
+ };
89
+ }
90
+
91
+ if (action.type === "UPDATE_PAYMENT") {
92
+ return {
93
+ ...action,
94
+ payload: {
95
+ ...action.payload,
96
+ cardNumber: null,
97
+ cvv: null,
98
+ },
99
+ };
100
+ }
101
+
102
+ // Include all other actions as-is
103
+ return action;
104
+ },
105
+ });
106
+ ```
107
+
108
+ ---
109
+
110
+ ### Options: `stateTransformer` — Filter/Scrub State Snapshots
111
+
112
+ Called on every state update.
113
+ Return the state to attach it to error events, a modified copy with sensitive fields
114
+ redacted, or `null` to exclude state entirely.
115
+
116
+ ```typescript
117
+ const sentryReduxEnhancer = Sentry.createReduxEnhancer({
118
+ stateTransformer: (state: RootState) => {
119
+ // Return null to send NO state with errors (reduces context but protects PII)
120
+ // if (state.topSecret.active) return null;
121
+
122
+ // Return a scrubbed copy
123
+ return {
124
+ ...state,
125
+ auth: {
126
+ ...state.auth,
127
+ token: null, // remove auth token
128
+ refreshToken: null,
129
+ password: null,
130
+ },
131
+ user: {
132
+ ...state.user,
133
+ ssn: "[REDACTED]",
134
+ creditCard: null,
135
+ dateOfBirth: null,
136
+ },
137
+ // Remove entire subtrees you don't need
138
+ cache: null,
139
+ rawApiResponses: null,
140
+ };
141
+ },
142
+ });
143
+ ```
144
+
145
+ > ⚠️ **Warning:** If `stateTransformer` returns `null`, error events will lack Redux
146
+ > state context. Debugging large state-dependent bugs becomes much harder.
147
+ > Prefer returning a filtered copy over returning `null`.
148
+
149
+ ---
150
+
151
+ ### Options: `configureScopeWithState` — Derive Sentry Tags from Redux State
152
+
153
+ Called after every state update.
154
+ Use it to keep Sentry scope tags/context in sync with your application’s Redux state —
155
+ these tags then appear on every error captured after the update.
156
+
157
+ ```typescript
158
+ const sentryReduxEnhancer = Sentry.createReduxEnhancer({
159
+ configureScopeWithState: (scope: Sentry.Scope, state: RootState) => {
160
+ // Tag events with current user plan (great for filtering errors by customer tier)
161
+ scope.setTag("user.plan", state.user.plan);
162
+ scope.setTag("user.id", state.user.id);
163
+
164
+ // Tag with feature flag state
165
+ scope.setTag("feature.newCheckout", String(state.features.newCheckout));
166
+ scope.setTag("feature.darkMode", String(state.settings.darkMode));
167
+
168
+ // Tag with routing/navigation state
169
+ scope.setTag("app.currentFlow", state.navigation.currentFlow);
170
+
171
+ // Conditional tags based on state shape
172
+ if (state.settings.useImperialUnits) {
173
+ scope.setTag("user.usesImperialUnits", "true");
174
+ }
175
+
176
+ // Set structured context (not searchable but visible in issue detail)
177
+ scope.setContext("cart", {
178
+ itemCount: state.cart.items.length,
179
+ total: state.cart.total,
180
+ coupon: state.cart.couponCode ?? null,
181
+ });
182
+ },
183
+ });
184
+ ```
185
+
186
+ ---
187
+
188
+ ### Options: `attachReduxState` — Control State File Attachment
189
+
190
+ Controls whether the Redux state (post-`stateTransformer`) is attached as a
191
+ `redux_state.json` file on error events.
192
+
193
+ - **Type:** `boolean`
194
+ - **Default:** `true`
195
+ - **Min SDK:** `7.69.0`
196
+
197
+ ```typescript
198
+ const sentryReduxEnhancer = Sentry.createReduxEnhancer({
199
+ attachReduxState: false, // Don't attach state file — reduces payload size
200
+ });
201
+ ```
202
+
203
+ ---
204
+
205
+ ### Options: `normalizeDepth` — Control State Serialization Depth
206
+
207
+ Set in `Sentry.init()`, not in `createReduxEnhancer()`. Increases the depth at which
208
+ Redux state trees are serialized.
209
+ The default of `3` is too shallow for most Redux state shapes.
210
+
211
+ ```typescript
212
+ Sentry.init({
213
+ dsn: "___PUBLIC_DSN___",
214
+ normalizeDepth: 10, // Default is 3 — increase for deeply nested Redux state
215
+ });
216
+ ```
217
+
218
+ ---
219
+
220
+ ### All Options Summary
221
+
222
+ | Option | Type | Default | Location | Description |
223
+ | ------------------------- | -------------------------------------- | ------- | ----------------------- | ------------------------------------------------- |
224
+ | `actionTransformer` | `(action: Action) => Action \| null` | — | `createReduxEnhancer()` | Modify or drop action breadcrumbs |
225
+ | `stateTransformer` | `(state: State) => State \| null` | — | `createReduxEnhancer()` | Modify or drop state attached to events |
226
+ | `configureScopeWithState` | `(scope: Scope, state: State) => void` | — | `createReduxEnhancer()` | Sync Sentry scope tags/context with Redux state |
227
+ | `attachReduxState` | `boolean` | `true` | `createReduxEnhancer()` | Attach state as `redux_state.json` file on errors |
228
+ | `normalizeDepth` | `number` | `3` | `Sentry.init()` | Max depth when serializing nested state |
229
+
230
+ ---
231
+
232
+ ### Complete Working Example with `@reduxjs/toolkit`
233
+
234
+ ```typescript
235
+ // store/sentry.ts
236
+ import * as Sentry from "@sentry/react";
237
+ import type { RootState } from "./types";
238
+
239
+ export const sentryReduxEnhancer = Sentry.createReduxEnhancer({
240
+ actionTransformer: (action) => {
241
+ // Drop noisy/sensitive action types
242
+ const DROP_TYPES = new Set([
243
+ "SET_AUTH_TOKEN",
244
+ "REFRESH_TOKEN",
245
+ "WEBSOCKET_HEARTBEAT",
246
+ "UPDATE_CURSOR_POSITION",
247
+ ]);
248
+ if (DROP_TYPES.has(action.type)) return null;
249
+
250
+ // Scrub passwords from login actions
251
+ if (action.type === "auth/login/pending") {
252
+ return {
253
+ ...action,
254
+ meta: { ...action.meta, arg: { email: action.meta?.arg?.email, password: "[REDACTED]" } },
255
+ };
256
+ }
257
+
258
+ return action;
259
+ },
260
+
261
+ stateTransformer: (state: RootState) => ({
262
+ ...state,
263
+ auth: { isAuthenticated: state.auth.isAuthenticated, userId: state.auth.userId },
264
+ // Strip large or sensitive subtrees
265
+ rawData: null,
266
+ }),
267
+
268
+ configureScopeWithState: (scope, state: RootState) => {
269
+ scope.setTag("user.plan", state.user.plan ?? "unknown");
270
+ scope.setTag("user.id", state.auth.userId ?? "anonymous");
271
+ scope.setTag("org.id", state.org.id ?? "none");
272
+ },
273
+ });
274
+
275
+ // store/index.ts
276
+ import { configureStore } from "@reduxjs/toolkit";
277
+ import { sentryReduxEnhancer } from "./sentry";
278
+ import rootReducer from "./reducers";
279
+
280
+ export const store = configureStore({
281
+ reducer: rootReducer,
282
+ enhancers: (getDefaultEnhancers) => getDefaultEnhancers().concat(sentryReduxEnhancer),
283
+ });
284
+ ```
285
+
286
+ ```typescript
287
+ // instrument.ts — init with normalizeDepth
288
+ import * as Sentry from "@sentry/react";
289
+
290
+ Sentry.init({
291
+ dsn: import.meta.env.VITE_SENTRY_DSN,
292
+ normalizeDepth: 10, // Required for deeply nested Redux state
293
+ integrations: [Sentry.browserTracingIntegration()],
294
+ tracesSampleRate: 1.0,
295
+ });
296
+ ```
297
+
298
+ ### Performance Considerations
299
+
300
+ Redux state can be very large.
301
+ Keep in mind:
302
+
303
+ 1. **State size:** Large state trees (thousands of items) will slow serialization and
304
+ increase payload size.
305
+ Use `stateTransformer` to return only the relevant slices.
306
+ 2. **`normalizeDepth`:** Keep it as low as practical.
307
+ `10` is usually sufficient for deeply nested state; avoid setting it to `Infinity`.
308
+ 3. **`attachReduxState: false`:** For high-traffic production apps where payload size is
309
+ a concern, disabling state attachment reduces each error event’s size.
310
+ 4. **`configureScopeWithState` cost:** This runs on every Redux dispatch.
311
+ Keep the function fast — avoid heavy computations or deep object traversals.
312
+
313
+ ---
314
+
315
+ ## 2. Component Tracking & Performance
316
+
317
+ ### A. React Component Name Annotation (Build-Time)
318
+
319
+ Replaces opaque CSS selectors in breadcrumbs, Session Replay, and performance spans with
320
+ readable React component names.
321
+
322
+ **Before:** `button.en302zp1.app-191aavw.e16hd6vm2[role="button"]`\
323
+ **After:** `CheckoutButton`
324
+
325
+ **Requirements:**
326
+
327
+ - SDK v7.91.0+
328
+ - Components must be in `.jsx` or `.tsx` files (`.js` and `.ts` are **not** annotated)
329
+ - esbuild is **not** supported
330
+
331
+ The bundler plugins inject `data-sentry-component` and `data-sentry-source-file`
332
+ attributes at build time:
333
+
334
+ ```html
335
+ <!-- Resulting DOM -->
336
+ <button data-sentry-component="CheckoutButton" data-sentry-source-file="CheckoutButton.tsx">
337
+ Checkout
338
+ </button>
339
+ ```
340
+
341
+ **Enable via Vite (recommended):**
342
+
343
+ ```typescript
344
+ // vite.config.ts
345
+ import { defineConfig } from "vite";
346
+ import react from "@vitejs/plugin-react";
347
+ import { sentryVitePlugin } from "@sentry/vite-plugin";
348
+
349
+ export default defineConfig({
350
+ plugins: [
351
+ react(),
352
+ sentryVitePlugin({
353
+ org: process.env.SENTRY_ORG,
354
+ project: process.env.SENTRY_PROJECT,
355
+ authToken: process.env.SENTRY_AUTH_TOKEN,
356
+ reactComponentAnnotation: {
357
+ enabled: true,
358
+ // Exclude components that cause "Passing unknown props on Fragment" errors
359
+ ignoredComponents: ["AnimationWrapper", "LayoutFragment"],
360
+ },
361
+ }),
362
+ ],
363
+ build: {
364
+ sourcemap: "hidden",
365
+ },
366
+ });
367
+ ```
368
+
369
+ **Enable via Babel plugin directly (without bundler plugin):**
370
+
371
+ ```bash
372
+ npm install @sentry/babel-plugin-component-annotate --save-dev
373
+ ```
374
+
375
+ ```javascript
376
+ // babel.config.js
377
+ module.exports = {
378
+ plugins: ["@sentry/babel-plugin-component-annotate"],
379
+ };
380
+ ```
381
+
382
+ **Bundler support:**
383
+
384
+ | Bundler | Component Annotation |
385
+ | ------- | -------------------- |
386
+ | Vite | ✅ Supported |
387
+ | Webpack | ✅ Supported |
388
+ | Rollup | ✅ Supported |
389
+ | esbuild | ❌ Not supported |
390
+
391
+ **What you gain:**
392
+
393
+ | Where | Before | After |
394
+ | ----------------- | ------------------- | ----------------------- |
395
+ | Breadcrumbs | `div.sc-abc123` | `ProductCard` |
396
+ | Session Replay | Unreadable selector | Search by `ProductCard` |
397
+ | Performance spans | Generic element | `CheckoutButton` render |
398
+
399
+ ---
400
+
401
+ ### B. `Sentry.withProfiler()` — React Profiler HOC
402
+
403
+ `withProfiler` wraps a component with the
404
+ [React Profiler API](https://react.dev/reference/react/Profiler) to capture render
405
+ timing as Sentry performance spans.
406
+
407
+ ```typescript
408
+ import * as Sentry from "@sentry/react";
409
+
410
+ // Basic — display name inferred from component.displayName or .name
411
+ const ProfiledDashboard = Sentry.withProfiler(Dashboard);
412
+
413
+ // With explicit name (required for anonymous or arrow-function components)
414
+ const ProfiledWidget = Sentry.withProfiler(
415
+ ({ data }) => <div>{data.title}</div>,
416
+ { name: "DataWidget" }
417
+ );
418
+
419
+ // Class component decorator syntax
420
+ @Sentry.withProfiler
421
+ class ExpensiveList extends React.Component {
422
+ render() {
423
+ return <ul>{this.props.items.map(renderItem)}</ul>;
424
+ }
425
+ }
426
+ ```
427
+
428
+ **Options:**
429
+
430
+ | Option | Type | Default | Description |
431
+ | ---------------- | --------- | --------------------------------- | ----------------------------------- |
432
+ | `name` | `string` | Component `displayName` or `name` | Display name shown in Sentry traces |
433
+ | `includeRender` | `boolean` | `true` | Track initial render phase |
434
+ | `includeUpdates` | `boolean` | `true` | Track re-render / update phases |
435
+
436
+ **What it captures:**
437
+
438
+ - Mount time (initial render duration)
439
+ - Update/re-render time per update
440
+ - Number of re-renders
441
+ - Component name in the Sentry performance trace waterfall
442
+
443
+ **Data appears in:** Sentry → Performance → Trace View, as child spans of the current
444
+ transaction.
445
+
446
+ > **Requires tracing:** `browserTracingIntegration` must be in your `Sentry.init`
447
+ > integrations.
448
+
449
+ **When to use (and when not to):**
450
+
451
+ ✅ Use on:
452
+
453
+ - Root-level route components (Dashboard, CheckoutFlow, UserProfile)
454
+ - Components with expensive render logic (large lists, complex calculations)
455
+ - Components that re-render frequently and may cause jank
456
+
457
+ ❌ Do **not** use on:
458
+
459
+ - Every component in the tree — the overhead compounds
460
+ - Simple presentational/leaf components
461
+ - Components that render hundreds of times per second (e.g., animation frames)
462
+
463
+ **Performance overhead:** Each profiled component adds a small constant overhead per
464
+ render cycle.
465
+ Profile the 5–10 most performance-critical components, not the entire tree.
466
+
467
+ ---
468
+
469
+ ## 3. Source Maps
470
+
471
+ Source maps translate minified production stack traces back to your original source
472
+ code. Without them, stack traces show obfuscated variable names and collapsed line
473
+ numbers.
474
+
475
+ ### Recommended: Sentry Wizard
476
+
477
+ The fastest path — automatically detects your bundler, installs the plugin, and
478
+ configures auth:
479
+
480
+ > **You need to run this yourself** — the wizard opens a browser for login and requires
481
+ > interactive input that the agent can’t handle.
482
+ > Copy-paste into your terminal:
483
+ >
484
+ > ```
485
+ > npx @sentry/wizard@latest -i sourcemaps
486
+ > ```
487
+ >
488
+ > It detects Vite/webpack/CRA, installs the appropriate Sentry bundler plugin, adds
489
+ > `SENTRY_AUTH_TOKEN` to `.env.sentry-build-plugin`, and configures
490
+ > `sourcemap: "hidden"` with `filesToDeleteAfterUpload`.
491
+ >
492
+ > **Once it finishes, come back and the agent will continue.**
493
+
494
+ If the user skips the wizard, proceed with manual bundler plugin setup below.
495
+
496
+ ---
497
+
498
+ ### How Debug IDs Work
499
+
500
+ Modern Sentry source map matching uses **Debug IDs** — unique identifiers injected by
501
+ the bundler plugin into both the compiled `.js` bundle and the corresponding `.js.map`
502
+ file. This makes source map matching reliable without needing to manage file names or
503
+ release artifacts manually.
504
+
505
+ **Flow:**
506
+
507
+ 1. Production build runs → bundler plugin injects a Debug ID into each `.js` and
508
+ `.js.map` file
509
+ 2. Plugin uploads `.js.map` files to Sentry with their Debug IDs
510
+ 3. Error occurs in production → stack frame contains the Debug ID
511
+ 4. Sentry uses the Debug ID to locate the exact source map → deobfuscates the trace
512
+
513
+ Debug IDs are more reliable than release-based matching (older approach) because they
514
+ don’t depend on consistent release naming or artifact upload timing.
515
+
516
+ ---
517
+
518
+ ### Vite Plugin
519
+
520
+ **Minimum SDK:** `@sentry/vite-plugin` `2.0.0` / `@sentry/react` `7.47.0`
521
+
522
+ ```bash
523
+ npm install @sentry/vite-plugin --save-dev
524
+ ```
525
+
526
+ ```typescript
527
+ // vite.config.ts
528
+ import { defineConfig } from "vite";
529
+ import react from "@vitejs/plugin-react";
530
+ import { sentryVitePlugin } from "@sentry/vite-plugin";
531
+
532
+ export default defineConfig({
533
+ build: {
534
+ // "hidden" generates source maps but strips the `//# sourceMappingURL=` comment
535
+ // from bundles, so browsers won't load them — they're only for Sentry.
536
+ sourcemap: "hidden",
537
+ },
538
+ plugins: [
539
+ react(),
540
+ // sentryVitePlugin MUST come after all other plugins
541
+ sentryVitePlugin({
542
+ org: process.env.SENTRY_ORG,
543
+ project: process.env.SENTRY_PROJECT,
544
+ authToken: process.env.SENTRY_AUTH_TOKEN,
545
+
546
+ // Enable React component name annotation at the same time
547
+ reactComponentAnnotation: {
548
+ enabled: true,
549
+ },
550
+
551
+ sourcemaps: {
552
+ // Delete .map files from dist/ after uploading to Sentry
553
+ // so they're not deployed to your CDN/server
554
+ filesToDeleteAfterUpload: [
555
+ "./**/*.map",
556
+ ".*/**/public/**/*.map",
557
+ "./dist/**/client/**/*.map",
558
+ ],
559
+ },
560
+ }),
561
+ ],
562
+ });
563
+ ```
564
+
565
+ > ⚠️ Place `sentryVitePlugin` **after** all other plugins (especially
566
+ > `@vitejs/plugin-react`) to ensure correct source map generation.
567
+
568
+ ---
569
+
570
+ ### Webpack Plugin
571
+
572
+ **Minimum SDK:** `@sentry/webpack-plugin` `2.0.0` / `@sentry/react` `7.47.0`
573
+
574
+ ```bash
575
+ npm install @sentry/webpack-plugin --save-dev
576
+ ```
577
+
578
+ ```javascript
579
+ // webpack.config.js
580
+ const { sentryWebpackPlugin } = require("@sentry/webpack-plugin");
581
+
582
+ module.exports = {
583
+ // "hidden-source-map" generates source maps without the `//# sourceMappingURL=`
584
+ // reference comment, so they won't be served publicly.
585
+ devtool: "hidden-source-map",
586
+
587
+ plugins: [
588
+ sentryWebpackPlugin({
589
+ org: process.env.SENTRY_ORG,
590
+ project: process.env.SENTRY_PROJECT,
591
+ authToken: process.env.SENTRY_AUTH_TOKEN,
592
+ sourcemaps: {
593
+ filesToDeleteAfterUpload: ["./**/*.map", "./build/static/**/*.map"],
594
+ },
595
+ }),
596
+ ],
597
+ };
598
+ ```
599
+
600
+ ---
601
+
602
+ ### Create React App
603
+
604
+ CRA has limited configuration access.
605
+ Two approaches:
606
+
607
+ **Option A: CRACO (recommended — no ejection)**
608
+
609
+ ```bash
610
+ npm install @craco/craco @sentry/webpack-plugin --save-dev
611
+ ```
612
+
613
+ ```javascript
614
+ // craco.config.js
615
+ const { sentryWebpackPlugin } = require("@sentry/webpack-plugin");
616
+
617
+ module.exports = {
618
+ webpack: {
619
+ configure: (webpackConfig) => {
620
+ webpackConfig.devtool = "hidden-source-map";
621
+ webpackConfig.plugins.push(
622
+ sentryWebpackPlugin({
623
+ org: process.env.SENTRY_ORG,
624
+ project: process.env.SENTRY_PROJECT,
625
+ authToken: process.env.SENTRY_AUTH_TOKEN,
626
+ sourcemaps: {
627
+ filesToDeleteAfterUpload: ["./build/static/**/*.map"],
628
+ },
629
+ }),
630
+ );
631
+ return webpackConfig;
632
+ },
633
+ },
634
+ };
635
+ ```
636
+
637
+ Update `package.json` scripts:
638
+
639
+ ```json
640
+ {
641
+ "scripts": {
642
+ "start": "craco start",
643
+ "build": "craco build"
644
+ }
645
+ }
646
+ ```
647
+
648
+ **Option B: Eject (`npm run eject`)**
649
+
650
+ After ejecting, edit `config/webpack.config.js` directly — same as the regular webpack
651
+ setup above. Ejection is irreversible; prefer CRACO.
652
+
653
+ ---
654
+
655
+ ### Manual Upload with `sentry-cli`
656
+
657
+ Use when you can’t use a bundler plugin (e.g., legacy toolchain, pre-built artifacts):
658
+
659
+ ```bash
660
+ npm install @sentry/cli --save-dev
661
+ ```
662
+
663
+ ```bash
664
+ # Upload source maps after a production build
665
+ npx sentry-cli sourcemaps upload \
666
+ --org $SENTRY_ORG \
667
+ --project $SENTRY_PROJECT \
668
+ --auth-token $SENTRY_AUTH_TOKEN \
669
+ ./build
670
+ ```
671
+
672
+ **`.sentryclirc` configuration file (alternative to env vars):**
673
+
674
+ ```ini
675
+ [defaults]
676
+ org = my-org-slug
677
+ project = my-project-slug
678
+ url = https://sentry.io/
679
+ ```
680
+
681
+ ```bash
682
+ # With .sentryclirc, no --org/--project flags needed:
683
+ npx sentry-cli sourcemaps upload --auth-token $SENTRY_AUTH_TOKEN ./build
684
+ ```
685
+
686
+ > ⚠️ Never commit `SENTRY_AUTH_TOKEN` to source control.
687
+ > Always read it from environment variables.
688
+
689
+ **CI/CD pattern (GitHub Actions):**
690
+
691
+ ```yaml
692
+ - name: Build
693
+ run: npm run build
694
+
695
+ - name: Upload source maps to Sentry
696
+ env:
697
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
698
+ SENTRY_ORG: my-org-slug
699
+ SENTRY_PROJECT: my-react-app
700
+ run: |
701
+ npx sentry-cli sourcemaps upload \
702
+ --org $SENTRY_ORG \
703
+ --project $SENTRY_PROJECT \
704
+ --auth-token $SENTRY_AUTH_TOKEN \
705
+ ./build
706
+
707
+ - name: Delete source maps from build artifacts
708
+ run: find ./build -name "*.map" -delete
709
+
710
+ - name: Deploy
711
+ run: # your deploy step
712
+ ```
713
+
714
+ ---
715
+
716
+ ### Environment Variables for Source Maps
717
+
718
+ Store credentials in `.env.sentry-build-plugin` (auto-loaded by Sentry bundler plugins)
719
+ or pass as CI/CD secrets:
720
+
721
+ ```bash
722
+ # .env.sentry-build-plugin ← auto-loaded by @sentry/vite-plugin and @sentry/webpack-plugin
723
+ # ADD THIS FILE TO .gitignore — never commit it
724
+ SENTRY_AUTH_TOKEN=sntrys_eyJ...
725
+ SENTRY_ORG=my-org-slug
726
+ SENTRY_PROJECT=my-project-slug
727
+ ```
728
+
729
+ **Required token permissions:**
730
+
731
+ The `SENTRY_AUTH_TOKEN` must have:
732
+
733
+ - **Project:** Read & Write
734
+ - **Release:** Admin
735
+
736
+ ---
737
+
738
+ ### Source Map Security
739
+
740
+ | Strategy | How |
741
+ | ------------------------------ | ---------------------------------------------------------------------------- |
742
+ | Don’t expose maps to browsers | Use `sourcemap: "hidden"` (Vite) or `devtool: "hidden-source-map"` (webpack) |
743
+ | Delete maps after upload | Use `filesToDeleteAfterUpload` in the plugin config |
744
+ | Block map access at CDN/server | Configure your server to return 403 for `.js.map` requests |
745
+
746
+ All three should be used together for maximum security.
747
+
748
+ ---
749
+
750
+ ### Troubleshooting Source Maps
751
+
752
+ | Problem | Likely Cause | Fix |
753
+ | ------------------------------------------ | -------------------------------------------------------- | -------------------------------------------------------------------------- |
754
+ | Stack traces still minified | Source maps not uploaded, or Debug IDs missing | Rebuild with production config, re-run wizard or plugin |
755
+ | Maps not applied to old errors | Maps uploaded after errors occurred | Always upload maps **before** deploying — ideally in the same CI step |
756
+ | “SourceMapDevToolPlugin” stripping sources | `noSources: true` in your webpack SourceMapDevToolPlugin | Remove `noSources: true` option |
757
+ | Plugin only uploads once | Running in `--watch` or dev mode | Plugin only uploads during production builds (`NODE_ENV=production`) |
758
+ | SENTRY_AUTH_TOKEN not found | Missing env variable | Check `.env.sentry-build-plugin` exists and is not gitignored incorrectly |
759
+ | Component names still not showing | `.js`/`.ts` files instead of `.jsx`/`.tsx` | Rename files or use the Babel plugin directly on all JSX transform targets |
760
+
761
+ ---
762
+
763
+ ## 4. Default Integrations
764
+
765
+ These integrations are **automatically enabled** for every `@sentry/react` installation.
766
+ No configuration required.
767
+
768
+ | Integration | Name Constant | What It Does |
769
+ | ------------------ | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
770
+ | Breadcrumbs | `breadcrumbsIntegration` | Captures breadcrumbs from DOM events (clicks, inputs), XHR, fetch, console calls, history navigation |
771
+ | Browser API Errors | `browserApiErrorsIntegration` | Wraps `setTimeout`, `setInterval`, `requestAnimationFrame`, `addEventListener`, `removeEventListener` in try/catch so errors inside them are captured |
772
+ | Browser Session | `browserSessionIntegration` | Tracks session health (healthy vs. crashed) for Release Health metrics |
773
+ | Dedupe | `dedupeIntegration` | Prevents duplicate error events from being sent — deduplicates based on error type, message, and stack trace |
774
+ | Function to String | `functionToStringIntegration` | Preserves original function `.toString()` output after SDK instrumentation, so stack traces show readable names |
775
+ | Global Handlers | `globalHandlersIntegration` | Listens to `window.onerror` (uncaught exceptions) and `window.onunhandledrejection` (unhandled promise rejections) |
776
+ | HTTP Context | `httpContextIntegration` | Attaches current URL, referrer, and user-agent to every event |
777
+ | Inbound Filters | `inboundFiltersIntegration` | Filters known-noisy events by error type, message, or URL (e.g., browser extension errors, localhost-only errors) |
778
+ | Linked Errors | `linkedErrorsIntegration` | Follows JavaScript `error.cause` chains and attaches nested errors as linked issues — also used for React component stack linkage |
779
+
780
+ ### Customizing a Default Integration’s Options
781
+
782
+ Pass the integration explicitly in `integrations` — it overrides the default instance:
783
+
784
+ ```typescript
785
+ Sentry.init({
786
+ dsn: "___PUBLIC_DSN___",
787
+ integrations: [
788
+ // Override breadcrumbs to disable console capturing but keep DOM/fetch/XHR
789
+ Sentry.breadcrumbsIntegration({
790
+ console: false, // don't capture console.log as breadcrumbs
791
+ dom: true,
792
+ fetch: true,
793
+ history: true,
794
+ xhr: true,
795
+ }),
796
+
797
+ // Only capture unhandled exceptions; handle rejections manually
798
+ Sentry.globalHandlersIntegration({
799
+ onerror: true,
800
+ onunhandledrejection: false,
801
+ }),
802
+ ],
803
+ });
804
+ ```
805
+
806
+ ### Removing a Default Integration
807
+
808
+ Use the function form of `integrations` to filter out what you don’t want:
809
+
810
+ ```typescript
811
+ Sentry.init({
812
+ dsn: "___PUBLIC_DSN___",
813
+ integrations: (integrations) => {
814
+ // Remove deduplication (e.g., if you want every occurrence recorded separately)
815
+ return integrations.filter((integration) => integration.name !== "Dedupe");
816
+ },
817
+ });
818
+ ```
819
+
820
+ Common integration names to filter:
821
+
822
+ - `"Dedupe"` — deduplication
823
+ - `"Breadcrumbs"` — all automatic breadcrumbs
824
+ - `"GlobalHandlers"` — window.onerror / unhandledrejection
825
+ - `"LinkedErrors"` — error cause chain following
826
+ - `"HttpContext"` — URL/referrer attachment
827
+ - `"InboundFilters"` — built-in noise filtering
828
+
829
+ ### Disabling ALL Default Integrations
830
+
831
+ ```typescript
832
+ Sentry.init({
833
+ dsn: "___PUBLIC_DSN___",
834
+ defaultIntegrations: false,
835
+ // Build your own set from scratch:
836
+ integrations: [
837
+ Sentry.globalHandlersIntegration(),
838
+ Sentry.browserTracingIntegration(),
839
+ Sentry.dedupeIntegration(),
840
+ ],
841
+ });
842
+ ```
843
+
844
+ ---
845
+
846
+ ## 5. Optional Integrations
847
+
848
+ These are available but **must be explicitly added** to your `integrations` array.
849
+
850
+ ### Performance & Tracing
851
+
852
+ | Integration | Min SDK | Description |
853
+ | ------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
854
+ | `browserTracingIntegration()` | 8.0.0 | Page load tracing, navigation tracing, automatic span creation for fetch/XHR, Core Web Vitals (LCP, FID, CLS), distributed tracing headers |
855
+ | `browserProfilingIntegration()` | 10.27.0 (Beta) | JS Self-Profiling API — captures call stacks at 100Hz in Chromium browsers. **Requires** `Document-Policy: js-profiling` HTTP header |
856
+
857
+ ### Session Replay
858
+
859
+ | Integration | Min SDK | Description |
860
+ | --------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
861
+ | `replayIntegration()` | 7.27.0 | Session Replay — records DOM mutations, network requests, console output. Configured with `replaysSessionSampleRate` and `replaysOnErrorSampleRate` |
862
+ | `replayCanvasIntegration()` | 7.98.0 | Extends `replayIntegration` to record `<canvas>` elements in replays |
863
+
864
+ ### Logging
865
+
866
+ | Integration | Min SDK | Description |
867
+ | ----------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
868
+ | `consoleLoggingIntegration()` | 9.41.0 | Automatically forwards `console.log/warn/error/info/debug` calls as structured Sentry logs. Requires `enableLogs: true` |
869
+
870
+ ```typescript
871
+ Sentry.init({
872
+ enableLogs: true,
873
+ integrations: [
874
+ Sentry.consoleLoggingIntegration({
875
+ levels: ["warn", "error"], // Only capture warnings and errors
876
+ }),
877
+ ],
878
+ });
879
+ ```
880
+
881
+ ### User Feedback
882
+
883
+ | Integration | Min SDK | Description |
884
+ | --------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------- |
885
+ | `feedbackIntegration()` | 7.85.0 | Floating feedback button + form (bottom-right). Supports screenshots, custom theming, programmatic control |
886
+ | `feedbackModalIntegration()` | 7.85.0 | Modal dialog variant of the feedback form |
887
+ | `feedbackScreenshotIntegration()` | 8.0.0 | Adds screenshot capture capability to the feedback widget |
888
+
889
+ ### Error Enhancement
890
+
891
+ | Integration | Min SDK | Description |
892
+ | -------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
893
+ | `extraErrorDataIntegration()` | 5.16.0 | Attaches non-standard properties on `Error` objects (e.g., `error.code`, `error.statusCode`, custom fields) as extra context |
894
+ | `contextLinesIntegration()` | 7.47.0 | Shows source code lines above and below the erroring line in the stack trace (requires source maps) |
895
+ | `httpClientIntegration()` | 7.50.0 | Captures failed HTTP requests (4xx/5xx responses) as Sentry error events, with request/response bodies. Opt-in because it may capture PII |
896
+ | `reportingObserverIntegration()` | 5.9.0 | Captures [Reporting Observer API](https://developer.mozilla.org/en-US/docs/Web/API/ReportingObserver) events (deprecation warnings, browser interventions, CSP violations) |
897
+ | `captureConsoleIntegration()` | 3.3.0 | Captures `console.error`/`console.warn` calls as Sentry issues (not logs). Legacy alternative to `consoleLoggingIntegration` |
898
+
899
+ ### Stack Frame Rewriting
900
+
901
+ | Integration | Min SDK | Description |
902
+ | ---------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
903
+ | `rewriteFramesIntegration()` | 5.7.0 | Rewrites stack frame file paths — useful for normalizing paths in monorepos, Docker containers, or when paths differ between build and deploy environments |
904
+
905
+ ---
906
+
907
+ ### `httpClientIntegration` — Full Setup
908
+
909
+ Captures HTTP requests that fail (4xx/5xx) as error events, with the request URL,
910
+ method, status code, and optionally request/response bodies.
911
+
912
+ ```typescript
913
+ Sentry.init({
914
+ dsn: "___PUBLIC_DSN___",
915
+ integrations: [
916
+ Sentry.httpClientIntegration({
917
+ // Capture errors for these HTTP status code ranges
918
+ failedRequestStatusCodes: [
919
+ [400, 499],
920
+ [500, 599],
921
+ ],
922
+
923
+ // Only capture errors for these URL patterns
924
+ failedRequestTargets: ["https://api.myapp.com", /^https:\/\/internal\.service\//],
925
+ }),
926
+ ],
927
+ dataCollection: {
928
+ // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
929
+ // https://docs.sentry.io/platforms/javascript/guides/react/configuration/options/#dataCollection
930
+ // userInfo: false,
931
+ // httpBodies: [],
932
+ },
933
+ });
934
+ ```
935
+
936
+ ### Adding Integrations After Init
937
+
938
+ If you need to add an integration after `Sentry.init()` has been called (e.g., after
939
+ user consent):
940
+
941
+ ```typescript
942
+ // After the user accepts analytics cookies:
943
+ Sentry.addIntegration(
944
+ Sentry.replayIntegration({
945
+ maskAllText: true,
946
+ blockAllMedia: true,
947
+ }),
948
+ );
949
+ ```
950
+
951
+ ### Lazy Loading Integrations (Code Splitting)
952
+
953
+ ```typescript
954
+ // Dynamic import (works with any bundler)
955
+ import("@sentry/browser").then((lazySentry) => {
956
+ Sentry.addIntegration(lazySentry.replayIntegration());
957
+ });
958
+
959
+ // CDN lazyLoadIntegration() — for Sentry loader script environments
960
+ async function enableFeedback() {
961
+ try {
962
+ const feedbackIntegration = await Sentry.lazyLoadIntegration("feedbackIntegration");
963
+ Sentry.addIntegration(feedbackIntegration({ colorScheme: "system" }));
964
+ } catch (e) {
965
+ // Ad-blockers or network failures — fail gracefully
966
+ console.warn("Could not load Sentry feedback integration", e);
967
+ }
968
+ }
969
+ ```
970
+
971
+ Lazy-loadable integrations: `replayIntegration`, `replayCanvasIntegration`,
972
+ `feedbackIntegration`, `feedbackModalIntegration`, `feedbackScreenshotIntegration`,
973
+ `captureConsoleIntegration`, `contextLinesIntegration`, `linkedErrorsIntegration`,
974
+ `dedupeIntegration`, `extraErrorDataIntegration`, `httpClientIntegration`,
975
+ `reportingObserverIntegration`, `rewriteFramesIntegration`,
976
+ `browserProfilingIntegration`
977
+
978
+ ---
979
+
980
+ ## 6. Build Tool Detection & Environment Variables
981
+
982
+ ### Detecting the Build Tool
983
+
984
+ ```bash
985
+ # Run from project root
986
+ ls vite.config.ts vite.config.js webpack.config.js webpack.config.ts \
987
+ craco.config.js next.config.js next.config.ts 2>/dev/null
988
+
989
+ cat package.json | grep -E '"vite"|"react-scripts"|"webpack"|"@craco"'
990
+ ```
991
+
992
+ | File/Package Found | Build Tool |
993
+ | ----------------------------------------- | -------------------------------------- |
994
+ | `vite.config.*` or `"vite"` in deps | Vite |
995
+ | `"react-scripts"` in deps | Create React App |
996
+ | `craco.config.js` or `"@craco/craco"` | CRA + CRACO |
997
+ | `webpack.config.*` or `"webpack"` in deps | Custom Webpack |
998
+ | `next.config.*` or `"next"` in deps | Next.js (use `@sentry/nextjs` instead) |
999
+
1000
+ ---
1001
+
1002
+ ### DSN Environment Variable Patterns
1003
+
1004
+ | Build Tool | Variable Name | How to Access in Code |
1005
+ | ---------------- | ---------------------- | ---------------------------------------------------------- |
1006
+ | Vite | `VITE_SENTRY_DSN` | `import.meta.env.VITE_SENTRY_DSN` |
1007
+ | Create React App | `REACT_APP_SENTRY_DSN` | `process.env.REACT_APP_SENTRY_DSN` |
1008
+ | Custom Webpack | `SENTRY_DSN` | `process.env.SENTRY_DSN` (requires `DefinePlugin`) |
1009
+ | Any | `SENTRY_DSN` | Build-time injection (not available at runtime in browser) |
1010
+
1011
+ **Vite — `.env` file:**
1012
+
1013
+ ```bash
1014
+ # .env.production
1015
+ VITE_SENTRY_DSN=https://<key>@<org>.ingest.sentry.io/<id>
1016
+ VITE_SENTRY_ENVIRONMENT=production
1017
+ ```
1018
+
1019
+ ```typescript
1020
+ // instrument.ts
1021
+ Sentry.init({
1022
+ dsn: import.meta.env.VITE_SENTRY_DSN,
1023
+ environment: import.meta.env.VITE_SENTRY_ENVIRONMENT ?? "development",
1024
+ });
1025
+ ```
1026
+
1027
+ **Create React App — `.env.production` file:**
1028
+
1029
+ ```bash
1030
+ # .env.production (committed — DSN is public)
1031
+ REACT_APP_SENTRY_DSN=https://<key>@<org>.ingest.sentry.io/<id>
1032
+ REACT_APP_SENTRY_ENVIRONMENT=production
1033
+ ```
1034
+
1035
+ ```typescript
1036
+ // instrument.ts
1037
+ Sentry.init({
1038
+ dsn: process.env.REACT_APP_SENTRY_DSN,
1039
+ environment: process.env.REACT_APP_SENTRY_ENVIRONMENT ?? "development",
1040
+ });
1041
+ ```
1042
+
1043
+ **Custom Webpack — `webpack.config.js` with `DefinePlugin`:**
1044
+
1045
+ ```javascript
1046
+ const webpack = require("webpack");
1047
+
1048
+ module.exports = {
1049
+ plugins: [
1050
+ new webpack.DefinePlugin({
1051
+ "process.env.SENTRY_DSN": JSON.stringify(process.env.SENTRY_DSN),
1052
+ "process.env.SENTRY_ENVIRONMENT": JSON.stringify(process.env.NODE_ENV ?? "development"),
1053
+ }),
1054
+ ],
1055
+ };
1056
+ ```
1057
+
1058
+ ```typescript
1059
+ // instrument.ts
1060
+ Sentry.init({
1061
+ dsn: process.env.SENTRY_DSN,
1062
+ environment: process.env.SENTRY_ENVIRONMENT,
1063
+ });
1064
+ ```
1065
+
1066
+ ---
1067
+
1068
+ ### Conditional Initialization (Development vs Production)
1069
+
1070
+ Prevent Sentry from running in local development to avoid polluting your issue inbox
1071
+ with dev noise:
1072
+
1073
+ ```typescript
1074
+ // instrument.ts
1075
+ import * as Sentry from "@sentry/react";
1076
+
1077
+ const IS_PRODUCTION =
1078
+ import.meta.env.PROD || // Vite
1079
+ process.env.NODE_ENV === "production"; // webpack / CRA
1080
+
1081
+ if (IS_PRODUCTION) {
1082
+ Sentry.init({
1083
+ dsn: import.meta.env.VITE_SENTRY_DSN, // or your env var pattern
1084
+ environment: "production",
1085
+ integrations: [
1086
+ Sentry.browserTracingIntegration(),
1087
+ Sentry.replayIntegration({
1088
+ maskAllText: false,
1089
+ blockAllMedia: false,
1090
+ }),
1091
+ ],
1092
+ tracesSampleRate: 0.2, // 20% in production
1093
+ replaysSessionSampleRate: 0.1,
1094
+ replaysOnErrorSampleRate: 1.0,
1095
+ });
1096
+ } else {
1097
+ // In development: optionally init with verbose debug and full sampling
1098
+ Sentry.init({
1099
+ dsn: import.meta.env.VITE_SENTRY_DSN,
1100
+ environment: "development",
1101
+ debug: true, // Verbose SDK logging
1102
+ tracesSampleRate: 1.0, // 100% in dev so nothing is missed
1103
+ integrations: [Sentry.browserTracingIntegration()],
1104
+ // No Replay in dev — too noisy
1105
+ });
1106
+ }
1107
+ ```
1108
+
1109
+ ---
1110
+
1111
+ ### Complete `instrument.ts` Reference — All Features
1112
+
1113
+ A kitchen-sink example combining every feature:
1114
+
1115
+ ```typescript
1116
+ // src/instrument.ts
1117
+ import * as Sentry from "@sentry/react";
1118
+
1119
+ Sentry.init({
1120
+ dsn: import.meta.env.VITE_SENTRY_DSN,
1121
+ environment: import.meta.env.VITE_APP_ENV ?? "production",
1122
+ release: import.meta.env.VITE_APP_VERSION,
1123
+
1124
+ // ── Integrations ─────────────────────────────────────────────
1125
+ integrations: [
1126
+ // Tracing (navigation + API + Core Web Vitals)
1127
+ Sentry.browserTracingIntegration(),
1128
+
1129
+ // Session Replay
1130
+ Sentry.replayIntegration({
1131
+ maskAllText: false,
1132
+ blockAllMedia: false,
1133
+ }),
1134
+
1135
+ // Profiling (Beta — Chromium only, needs Document-Policy header)
1136
+ // Sentry.browserProfilingIntegration(),
1137
+
1138
+ // Structured logging (requires enableLogs: true)
1139
+ Sentry.consoleLoggingIntegration({
1140
+ levels: ["warn", "error"],
1141
+ }),
1142
+
1143
+ // Capture HTTP 4xx/5xx as Sentry errors
1144
+ Sentry.httpClientIntegration({
1145
+ failedRequestStatusCodes: [
1146
+ [400, 499],
1147
+ [500, 599],
1148
+ ],
1149
+ }),
1150
+
1151
+ // Show source lines in stack traces (requires source maps)
1152
+ Sentry.contextLinesIntegration(),
1153
+
1154
+ // Capture non-standard Error properties
1155
+ Sentry.extraErrorDataIntegration(),
1156
+
1157
+ // User feedback widget
1158
+ Sentry.feedbackIntegration({
1159
+ colorScheme: "system",
1160
+ showBranding: false,
1161
+ triggerLabel: "Report a Bug",
1162
+ }),
1163
+ ],
1164
+
1165
+ // ── Tracing ───────────────────────────────────────────────────
1166
+ tracesSampleRate: 0.2,
1167
+ tracePropagationTargets: ["localhost", /^https:\/\/api\.myapp\.com/],
1168
+
1169
+ // ── Session Replay ────────────────────────────────────────────
1170
+ replaysSessionSampleRate: 0.1,
1171
+ replaysOnErrorSampleRate: 1.0,
1172
+
1173
+ // ── Profiling ─────────────────────────────────────────────────
1174
+ profileSessionSampleRate: 1.0,
1175
+
1176
+ // ── Logging ───────────────────────────────────────────────────
1177
+ enableLogs: true,
1178
+ beforeSendLog: (log) => {
1179
+ if (log.level === "debug") return null; // Drop debug logs
1180
+ if (log.attributes?.password) delete log.attributes.password;
1181
+ return log;
1182
+ },
1183
+
1184
+ // ── Redux ─────────────────────────────────────────────────────
1185
+ normalizeDepth: 10,
1186
+
1187
+ // ── Filtering ─────────────────────────────────────────────────
1188
+ ignoreErrors: ["ResizeObserver loop limit exceeded", /^Loading chunk \d+ failed/],
1189
+ denyUrls: [/extensions\//i, /^chrome:\/\//i],
1190
+
1191
+ beforeSend(event) {
1192
+ // Strip credit card numbers from messages just in case
1193
+ if (event.message) {
1194
+ event.message = event.message.replace(/\b\d{16}\b/g, "[CARD]");
1195
+ }
1196
+ return event;
1197
+ },
1198
+ });
1199
+ ```
1200
+
1201
+ ```typescript
1202
+ // store/index.ts — wire in Redux enhancer
1203
+ import { configureStore } from "@reduxjs/toolkit";
1204
+ import * as Sentry from "@sentry/react";
1205
+
1206
+ export const store = configureStore({
1207
+ reducer: rootReducer,
1208
+ enhancers: (getDefaultEnhancers) =>
1209
+ getDefaultEnhancers().concat(
1210
+ Sentry.createReduxEnhancer({
1211
+ stateTransformer: (state) => ({ ...state, auth: null }),
1212
+ configureScopeWithState: (scope, state) => {
1213
+ scope.setTag("user.plan", state.user.plan);
1214
+ },
1215
+ }),
1216
+ ),
1217
+ });
1218
+ ```
1219
+
1220
+ ---
1221
+
1222
+ ## Quick Reference
1223
+
1224
+ ```typescript
1225
+ // ── Redux ─────────────────────────────────────────────────────
1226
+ Sentry.createReduxEnhancer({
1227
+ actionTransformer: (action) => action | null,
1228
+ stateTransformer: (state) => state | null,
1229
+ configureScopeWithState: (scope, state) => void,
1230
+ attachReduxState: true,
1231
+ })
1232
+ // normalizeDepth goes in Sentry.init(), not createReduxEnhancer()
1233
+
1234
+ // ── Component Tracking ────────────────────────────────────────
1235
+ Sentry.withProfiler(Component, { name?, includeRender?, includeUpdates? })
1236
+ sentryVitePlugin({ reactComponentAnnotation: { enabled: true, ignoredComponents: [] } })
1237
+ // Babel plugin direct: @sentry/babel-plugin-component-annotate
1238
+
1239
+ // ── Source Maps ───────────────────────────────────────────────
1240
+ npx @sentry/wizard@latest -i sourcemaps // automated setup
1241
+ // Vite: build.sourcemap = "hidden" + sentryVitePlugin()
1242
+ // Webpack: devtool: "hidden-source-map" + sentryWebpackPlugin()
1243
+ // CRA: use CRACO + sentryWebpackPlugin
1244
+ // Manual: npx sentry-cli sourcemaps upload --auth-token $TOKEN ./dist
1245
+
1246
+ // ── Integrations (opt-in) ─────────────────────────────────────
1247
+ Sentry.browserTracingIntegration() // Tracing + Core Web Vitals
1248
+ Sentry.replayIntegration() // Session Replay
1249
+ Sentry.browserProfilingIntegration() // JS Profiler (Beta, Chromium only)
1250
+ Sentry.consoleLoggingIntegration() // console → Sentry logs
1251
+ Sentry.feedbackIntegration() // Feedback widget
1252
+ Sentry.httpClientIntegration() // 4xx/5xx as errors
1253
+ Sentry.contextLinesIntegration() // Source lines in stack traces
1254
+ Sentry.extraErrorDataIntegration() // Non-standard Error properties
1255
+ Sentry.reportingObserverIntegration() // Browser deprecation/CSP reports
1256
+ Sentry.rewriteFramesIntegration() // Rewrite stack frame paths
1257
+ Sentry.captureConsoleIntegration() // console → Sentry issues (legacy)
1258
+
1259
+ // ── Remove a Default Integration ─────────────────────────────
1260
+ Sentry.init({
1261
+ integrations: (integrations) =>
1262
+ integrations.filter((i) => i.name !== "Dedupe"),
1263
+ })
1264
+
1265
+ // ── Add Integration After Init ────────────────────────────────
1266
+ Sentry.addIntegration(Sentry.replayIntegration())
1267
+
1268
+ // ── Environment Variables ─────────────────────────────────────
1269
+ // Vite: import.meta.env.VITE_SENTRY_DSN
1270
+ // CRA: process.env.REACT_APP_SENTRY_DSN
1271
+ // Webpack: process.env.SENTRY_DSN (via DefinePlugin)
1272
+ ```