@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.
- package/README.md +6 -6
- package/package.json +1 -1
- package/skill-sources.jsonc +2 -33
- package/skill-sources.lock.json +15 -117
- package/skills/animate/LICENSE +21 -0
- package/skills/animate/NOTICE +10 -0
- package/skills/animate/SKILL.md +34 -0
- package/skills/animate/references/gestures.md +27 -0
- package/skills/animate/references/glossary.md +136 -0
- package/skills/animate/references/implementation.md +22 -0
- package/skills/animate/references/opportunities.md +18 -0
- package/skills/animate/references/principles.md +48 -0
- package/skills/animate/references/review.md +19 -0
- package/skills/cloudflare-workers/LICENSE +202 -0
- package/skills/cloudflare-workers/NOTICE +9 -0
- package/skills/cloudflare-workers/SKILL.md +26 -0
- package/skills/cloudflare-workers/references/durable-objects.md +68 -0
- package/skills/cloudflare-workers/references/sandbox.md +48 -0
- package/skills/cloudflare-workers/references/workers.md +63 -0
- package/skills/cloudflare-workers/references/wrangler.md +56 -0
- package/skills/design-ui/LICENSE +21 -0
- package/skills/design-ui/NOTICE +8 -0
- package/skills/design-ui/SKILL.md +29 -0
- package/skills/design-ui/references/appearance.md +22 -0
- package/skills/design-ui/references/components.md +33 -0
- package/skills/design-ui/references/exploration.md +50 -0
- package/skills/design-ui/references/libraries.md +39 -0
- package/skills/design-ui/references/themes.md +23 -0
- package/skills/dev-kit/SKILL.md +19 -38
- package/skills/dev-kit/references/cloudflare-worker-api.md +1 -1
- package/skills/dev-kit/references/skills.md +2 -2
- package/skills/effect-development/SKILL.md +27 -0
- package/skills/effect-development/agents/openai.yaml +4 -0
- package/skills/effect-development/references/api/index.md +32 -0
- package/skills/effect-development/references/api/schema-codecs.md +15 -0
- package/skills/{build-effect-apis/references → effect-development/references/api}/verification.md +10 -5
- package/skills/{effect-architecture-audit/SKILL.md → effect-development/references/architecture/index.md} +1 -6
- package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-client.md +8 -6
- package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-testing.md +7 -2
- package/skills/effect-development/references/atom/index.md +40 -0
- package/skills/{build-effect-clis/references → effect-development/references/cli}/entrypoints-and-testing.md +6 -2
- package/skills/effect-development/references/cli/index.md +39 -0
- package/skills/effect-development/references/setup.md +15 -0
- package/skills/open-pull-request/SKILL.md +10 -70
- package/skills/open-pull-request/references/evidence.md +22 -0
- package/skills/open-pull-request/references/explanation.md +21 -0
- package/skills/open-pull-request/references/publication.md +21 -0
- package/skills/sentry/LICENSE +202 -0
- package/skills/sentry/LICENSE-UPSTREAM +21 -0
- package/skills/sentry/NOTICE +14 -0
- package/skills/sentry/SKILL.md +33 -0
- package/skills/sentry/references/alert-payloads.md +105 -0
- package/skills/sentry/references/alerts.md +17 -0
- package/skills/sentry/references/artifacts.md +25 -0
- package/skills/sentry/references/auth-token.md +65 -0
- package/skills/sentry/references/concepts/ai-monitoring.md +131 -0
- package/skills/sentry/references/concepts/choosing-a-signal.md +78 -0
- package/skills/sentry/references/concepts/crons.md +50 -0
- package/skills/sentry/references/concepts/data-scrubbing.md +43 -0
- package/skills/sentry/references/concepts/errors.md +40 -0
- package/skills/sentry/references/concepts/logging.md +85 -0
- package/skills/sentry/references/concepts/metrics.md +49 -0
- package/skills/sentry/references/concepts/monitors.md +78 -0
- package/skills/sentry/references/concepts/profiling.md +38 -0
- package/skills/sentry/references/concepts/reduce-volume.md +49 -0
- package/skills/sentry/references/concepts/releases.md +43 -0
- package/skills/sentry/references/concepts/session-replay.md +35 -0
- package/skills/sentry/references/concepts/tracing.md +54 -0
- package/skills/sentry/references/concepts/user-feedback.md +36 -0
- package/skills/sentry/references/debug-artifacts/android.md +68 -0
- package/skills/sentry/references/debug-artifacts/apple.md +96 -0
- package/skills/sentry/references/debug-artifacts/dotnet.md +70 -0
- package/skills/sentry/references/debug-artifacts/flutter.md +65 -0
- package/skills/sentry/references/debug-artifacts/index.md +75 -0
- package/skills/sentry/references/debug-artifacts/javascript.md +94 -0
- package/skills/sentry/references/debug-artifacts/matching.md +73 -0
- package/skills/sentry/references/debug-artifacts/react-native.md +75 -0
- package/skills/sentry/references/first-error-setup.md +25 -0
- package/skills/sentry/references/instrumentation.md +30 -0
- package/skills/sentry/references/issues.md +32 -0
- package/skills/sentry/references/new-project.md +17 -0
- package/skills/sentry/references/otel-exporter.md +30 -0
- package/skills/sentry/references/release-workflow.md +31 -0
- package/skills/sentry/references/releases/ci-pipeline.md +214 -0
- package/skills/sentry/references/releases/index.md +93 -0
- package/skills/sentry/references/releases/suspect-commits.md +155 -0
- package/skills/sentry/references/releases/tagging.md +131 -0
- package/skills/sentry/references/releases/troubleshooting.md +67 -0
- package/skills/sentry/references/sdks/android/crons.md +305 -0
- package/skills/sentry/references/sdks/android/error-monitoring.md +800 -0
- package/skills/sentry/references/sdks/android/index.md +748 -0
- package/skills/sentry/references/sdks/android/integrations.md +48 -0
- package/skills/sentry/references/sdks/android/logging.md +374 -0
- package/skills/sentry/references/sdks/android/metrics.md +288 -0
- package/skills/sentry/references/sdks/android/profiling.md +397 -0
- package/skills/sentry/references/sdks/android/session-replay.md +406 -0
- package/skills/sentry/references/sdks/android/tracing.md +861 -0
- package/skills/sentry/references/sdks/browser/error-monitoring.md +861 -0
- package/skills/sentry/references/sdks/browser/index.md +714 -0
- package/skills/sentry/references/sdks/browser/logging.md +315 -0
- package/skills/sentry/references/sdks/browser/profiling.md +236 -0
- package/skills/sentry/references/sdks/browser/session-replay.md +586 -0
- package/skills/sentry/references/sdks/browser/tracing.md +561 -0
- package/skills/sentry/references/sdks/browser/user-feedback.md +354 -0
- package/skills/sentry/references/sdks/cloudflare/ai-monitoring.md +661 -0
- package/skills/sentry/references/sdks/cloudflare/crons.md +231 -0
- package/skills/sentry/references/sdks/cloudflare/durable-objects.md +381 -0
- package/skills/sentry/references/sdks/cloudflare/error-monitoring.md +329 -0
- package/skills/sentry/references/sdks/cloudflare/index.md +698 -0
- package/skills/sentry/references/sdks/cloudflare/logging.md +169 -0
- package/skills/sentry/references/sdks/cloudflare/nodejs-compat.md +134 -0
- package/skills/sentry/references/sdks/cloudflare/tracing.md +475 -0
- package/skills/sentry/references/sdks/cocoa/error-monitoring.md +394 -0
- package/skills/sentry/references/sdks/cocoa/index.md +497 -0
- package/skills/sentry/references/sdks/cocoa/logging.md +209 -0
- package/skills/sentry/references/sdks/cocoa/metrics.md +136 -0
- package/skills/sentry/references/sdks/cocoa/profiling.md +223 -0
- package/skills/sentry/references/sdks/cocoa/session-replay.md +257 -0
- package/skills/sentry/references/sdks/cocoa/tracing.md +524 -0
- package/skills/sentry/references/sdks/cocoa/user-feedback.md +310 -0
- package/skills/sentry/references/sdks/dotnet/crons.md +465 -0
- package/skills/sentry/references/sdks/dotnet/error-monitoring.md +1100 -0
- package/skills/sentry/references/sdks/dotnet/index.md +614 -0
- package/skills/sentry/references/sdks/dotnet/logging.md +556 -0
- package/skills/sentry/references/sdks/dotnet/metrics.md +229 -0
- package/skills/sentry/references/sdks/dotnet/profiling.md +296 -0
- package/skills/sentry/references/sdks/dotnet/tracing.md +897 -0
- package/skills/sentry/references/sdks/elixir/crons.md +371 -0
- package/skills/sentry/references/sdks/elixir/error-monitoring.md +335 -0
- package/skills/sentry/references/sdks/elixir/index.md +383 -0
- package/skills/sentry/references/sdks/elixir/logging.md +239 -0
- package/skills/sentry/references/sdks/elixir/tracing.md +233 -0
- package/skills/sentry/references/sdks/flutter/ecosystem-integrations.md +70 -0
- package/skills/sentry/references/sdks/flutter/error-monitoring.md +312 -0
- package/skills/sentry/references/sdks/flutter/index.md +728 -0
- package/skills/sentry/references/sdks/flutter/logging.md +387 -0
- package/skills/sentry/references/sdks/flutter/metrics.md +310 -0
- package/skills/sentry/references/sdks/flutter/profiling.md +214 -0
- package/skills/sentry/references/sdks/flutter/session-replay.md +308 -0
- package/skills/sentry/references/sdks/flutter/tracing.md +502 -0
- package/skills/sentry/references/sdks/go/crons.md +270 -0
- package/skills/sentry/references/sdks/go/error-monitoring.md +361 -0
- package/skills/sentry/references/sdks/go/index.md +324 -0
- package/skills/sentry/references/sdks/go/logging.md +354 -0
- package/skills/sentry/references/sdks/go/metrics.md +273 -0
- package/skills/sentry/references/sdks/go/profiling.md +46 -0
- package/skills/sentry/references/sdks/go/tracing.md +366 -0
- package/skills/sentry/references/sdks/index.md +41 -0
- package/skills/sentry/references/sdks/nestjs/ai-monitoring.md +410 -0
- package/skills/sentry/references/sdks/nestjs/crons.md +268 -0
- package/skills/sentry/references/sdks/nestjs/error-monitoring.md +729 -0
- package/skills/sentry/references/sdks/nestjs/index.md +699 -0
- package/skills/sentry/references/sdks/nestjs/logging.md +174 -0
- package/skills/sentry/references/sdks/nestjs/metrics.md +243 -0
- package/skills/sentry/references/sdks/nestjs/profiling.md +127 -0
- package/skills/sentry/references/sdks/nestjs/tracing.md +762 -0
- package/skills/sentry/references/sdks/nextjs/ai-monitoring.md +494 -0
- package/skills/sentry/references/sdks/nextjs/crons.md +383 -0
- package/skills/sentry/references/sdks/nextjs/error-monitoring.md +974 -0
- package/skills/sentry/references/sdks/nextjs/index.md +491 -0
- package/skills/sentry/references/sdks/nextjs/logging.md +381 -0
- package/skills/sentry/references/sdks/nextjs/metrics.md +411 -0
- package/skills/sentry/references/sdks/nextjs/profiling.md +403 -0
- package/skills/sentry/references/sdks/nextjs/session-replay.md +462 -0
- package/skills/sentry/references/sdks/nextjs/tracing.md +628 -0
- package/skills/sentry/references/sdks/node/ai-monitoring.md +303 -0
- package/skills/sentry/references/sdks/node/crons.md +432 -0
- package/skills/sentry/references/sdks/node/error-monitoring.md +1125 -0
- package/skills/sentry/references/sdks/node/index.md +942 -0
- package/skills/sentry/references/sdks/node/logging.md +380 -0
- package/skills/sentry/references/sdks/node/metrics.md +278 -0
- package/skills/sentry/references/sdks/node/profiling.md +373 -0
- package/skills/sentry/references/sdks/node/tracing.md +878 -0
- package/skills/sentry/references/sdks/php/ai-monitoring.md +310 -0
- package/skills/sentry/references/sdks/php/crons.md +265 -0
- package/skills/sentry/references/sdks/php/error-monitoring.md +626 -0
- package/skills/sentry/references/sdks/php/index.md +362 -0
- package/skills/sentry/references/sdks/php/laravel.md +542 -0
- package/skills/sentry/references/sdks/php/logging.md +242 -0
- package/skills/sentry/references/sdks/php/metrics.md +193 -0
- package/skills/sentry/references/sdks/php/profiling.md +115 -0
- package/skills/sentry/references/sdks/php/symfony.md +552 -0
- package/skills/sentry/references/sdks/php/tracing.md +516 -0
- package/skills/sentry/references/sdks/python/ai-monitoring.md +351 -0
- package/skills/sentry/references/sdks/python/crons.md +218 -0
- package/skills/sentry/references/sdks/python/error-monitoring.md +292 -0
- package/skills/sentry/references/sdks/python/index.md +361 -0
- package/skills/sentry/references/sdks/python/logging.md +234 -0
- package/skills/sentry/references/sdks/python/metrics.md +154 -0
- package/skills/sentry/references/sdks/python/profiling.md +120 -0
- package/skills/sentry/references/sdks/python/tracing.md +364 -0
- package/skills/sentry/references/sdks/react/error-monitoring.md +1607 -0
- package/skills/sentry/references/sdks/react/index.md +492 -0
- package/skills/sentry/references/sdks/react/logging.md +364 -0
- package/skills/sentry/references/sdks/react/profiling.md +322 -0
- package/skills/sentry/references/sdks/react/react-features.md +1272 -0
- package/skills/sentry/references/sdks/react/session-replay.md +1193 -0
- package/skills/sentry/references/sdks/react/tracing.md +1415 -0
- package/skills/sentry/references/sdks/react-native/error-monitoring.md +1481 -0
- package/skills/sentry/references/sdks/react-native/expo-config-plugin.md +45 -0
- package/skills/sentry/references/sdks/react-native/index.md +1030 -0
- package/skills/sentry/references/sdks/react-native/logging.md +444 -0
- package/skills/sentry/references/sdks/react-native/profiling.md +386 -0
- package/skills/sentry/references/sdks/react-native/session-replay.md +704 -0
- package/skills/sentry/references/sdks/react-native/tracing.md +1086 -0
- package/skills/sentry/references/sdks/react-native/user-feedback.md +815 -0
- package/skills/sentry/references/sdks/react-router-framework/error-monitoring.md +127 -0
- package/skills/sentry/references/sdks/react-router-framework/index.md +411 -0
- package/skills/sentry/references/sdks/react-router-framework/logging.md +66 -0
- package/skills/sentry/references/sdks/react-router-framework/profiling.md +57 -0
- package/skills/sentry/references/sdks/react-router-framework/react-router-framework-features.md +110 -0
- package/skills/sentry/references/sdks/react-router-framework/session-replay.md +67 -0
- package/skills/sentry/references/sdks/react-router-framework/tracing.md +96 -0
- package/skills/sentry/references/sdks/react-router-framework/user-feedback.md +71 -0
- package/skills/sentry/references/sdks/ruby/crons.md +184 -0
- package/skills/sentry/references/sdks/ruby/error-monitoring.md +248 -0
- package/skills/sentry/references/sdks/ruby/index.md +297 -0
- package/skills/sentry/references/sdks/ruby/logging.md +168 -0
- package/skills/sentry/references/sdks/ruby/metrics.md +196 -0
- package/skills/sentry/references/sdks/ruby/migration.md +321 -0
- package/skills/sentry/references/sdks/ruby/profiling.md +107 -0
- package/skills/sentry/references/sdks/ruby/tracing.md +388 -0
- package/skills/sentry/references/sdks/svelte/error-monitoring.md +456 -0
- package/skills/sentry/references/sdks/svelte/index.md +467 -0
- package/skills/sentry/references/sdks/svelte/logging.md +344 -0
- package/skills/sentry/references/sdks/svelte/session-replay.md +369 -0
- package/skills/sentry/references/sdks/svelte/tracing.md +406 -0
- package/skills/sentry/references/sdks/tanstack-start/error-monitoring.md +149 -0
- package/skills/sentry/references/sdks/tanstack-start/index.md +381 -0
- package/skills/sentry/references/sdks/tanstack-start/logging.md +74 -0
- package/skills/sentry/references/sdks/tanstack-start/session-replay.md +76 -0
- package/skills/sentry/references/sdks/tanstack-start/tanstackstart-features.md +128 -0
- package/skills/sentry/references/sdks/tanstack-start/tracing.md +123 -0
- package/skills/sentry/references/sdks/tanstack-start/user-feedback.md +81 -0
- package/skills/sentry/references/search-query-language.md +226 -0
- package/skills/sentry/references/semantics/angular.md +7 -0
- package/skills/sentry/references/semantics/app.md +28 -0
- package/skills/sentry/references/semantics/art.md +17 -0
- package/skills/sentry/references/semantics/aws.md +43 -0
- package/skills/sentry/references/semantics/browser.md +34 -0
- package/skills/sentry/references/semantics/cache.md +12 -0
- package/skills/sentry/references/semantics/client.md +8 -0
- package/skills/sentry/references/semantics/cloud.md +12 -0
- package/skills/sentry/references/semantics/cloudflare.md +23 -0
- package/skills/sentry/references/semantics/code.md +11 -0
- package/skills/sentry/references/semantics/culture.md +11 -0
- package/skills/sentry/references/semantics/db.md +21 -0
- package/skills/sentry/references/semantics/device.md +43 -0
- package/skills/sentry/references/semantics/error.md +7 -0
- package/skills/sentry/references/semantics/event.md +8 -0
- package/skills/sentry/references/semantics/exception.md +10 -0
- package/skills/sentry/references/semantics/faas.md +19 -0
- package/skills/sentry/references/semantics/file.md +8 -0
- package/skills/sentry/references/semantics/flag.md +7 -0
- package/skills/sentry/references/semantics/gcp.md +16 -0
- package/skills/sentry/references/semantics/gen_ai.md +53 -0
- package/skills/sentry/references/semantics/general.md +11 -0
- package/skills/sentry/references/semantics/graphql.md +9 -0
- package/skills/sentry/references/semantics/grpc.md +19 -0
- package/skills/sentry/references/semantics/http.md +34 -0
- package/skills/sentry/references/semantics/index.md +63 -0
- package/skills/sentry/references/semantics/jsonrpc.md +8 -0
- package/skills/sentry/references/semantics/jvm.md +12 -0
- package/skills/sentry/references/semantics/koa.md +7 -0
- package/skills/sentry/references/semantics/logger.md +7 -0
- package/skills/sentry/references/semantics/mcp.md +37 -0
- package/skills/sentry/references/semantics/mdc.md +7 -0
- package/skills/sentry/references/semantics/messaging.md +23 -0
- package/skills/sentry/references/semantics/middleware.md +7 -0
- package/skills/sentry/references/semantics/navigation.md +9 -0
- package/skills/sentry/references/semantics/nel.md +11 -0
- package/skills/sentry/references/semantics/network.md +17 -0
- package/skills/sentry/references/semantics/os.md +15 -0
- package/skills/sentry/references/semantics/otel.md +10 -0
- package/skills/sentry/references/semantics/params.md +7 -0
- package/skills/sentry/references/semantics/process.md +14 -0
- package/skills/sentry/references/semantics/react.md +7 -0
- package/skills/sentry/references/semantics/remix.md +7 -0
- package/skills/sentry/references/semantics/resource.md +7 -0
- package/skills/sentry/references/semantics/rpc.md +10 -0
- package/skills/sentry/references/semantics/score.md +10 -0
- package/skills/sentry/references/semantics/sentry.md +69 -0
- package/skills/sentry/references/semantics/server.md +8 -0
- package/skills/sentry/references/semantics/service.md +8 -0
- package/skills/sentry/references/semantics/session.md +7 -0
- package/skills/sentry/references/semantics/state.md +7 -0
- package/skills/sentry/references/semantics/thread.md +8 -0
- package/skills/sentry/references/semantics/timber.md +7 -0
- package/skills/sentry/references/semantics/trpc.md +8 -0
- package/skills/sentry/references/semantics/ui.md +18 -0
- package/skills/sentry/references/semantics/url.md +15 -0
- package/skills/sentry/references/semantics/user.md +17 -0
- package/skills/sentry/references/semantics/user_agent.md +7 -0
- package/skills/sentry/references/semantics/vercel.md +42 -0
- package/skills/sentry/references/setup-verification.md +39 -0
- package/skills/sentry/references/snapshots/github-actions-fanout.md +206 -0
- package/skills/sentry/references/snapshots/github-actions-simple.md +102 -0
- package/skills/sentry/references/snapshots/github-actions-swift-snapshot-testing.md +118 -0
- package/skills/sentry/references/snapshots/index.md +19 -0
- package/skills/sentry/references/snapshots/snapshot-previews.md +100 -0
- package/skills/sentry/references/snapshots/snapshots.md +123 -0
- package/skills/sentry/references/snapshots/wizard-setup.md +134 -0
- package/skills/testing/LICENSE +21 -0
- package/skills/testing/NOTICE +7 -0
- package/skills/testing/SKILL.md +13 -19
- package/skills/testing/agents/openai.yaml +1 -2
- package/skills/testing/references/selection.md +23 -0
- package/skills/testing/references/tdd.md +19 -0
- package/skills/testing/references/test-design.md +17 -0
- package/src/catalog.ts +1 -7
- package/skills/build-effect-apis/SKILL.md +0 -81
- package/skills/build-effect-apis/agents/openai.yaml +0 -4
- package/skills/build-effect-clis/SKILL.md +0 -92
- package/skills/build-effect-clis/agents/openai.yaml +0 -4
- package/skills/effect-architecture-audit/agents/openai.yaml +0 -4
- package/skills/effect-atom-state/SKILL.md +0 -97
- package/skills/effect-atom-state/agents/openai.yaml +0 -4
- package/skills/effect-ts/SKILL.md +0 -35
- package/skills/effect-ts/agents/openai.yaml +0 -4
- /package/skills/{build-effect-apis/references → effect-development/references/api}/cloudflare-workers.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/runtime-assembly.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/server-and-middleware.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/shared-contracts.md +0 -0
- /package/skills/{effect-architecture-audit/references → effect-development/references/architecture}/service-and-boundary-audit.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-lifecycle.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-workflows.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/tanstack-start.md +0 -0
- /package/skills/{build-effect-clis/references → effect-development/references/cli}/command-design.md +0 -0
- /package/skills/{build-effect-clis/references → effect-development/references/cli}/processes-and-platform.md +0 -0
|
@@ -0,0 +1,1086 @@
|
|
|
1
|
+
# Tracing & Performance Monitoring — Sentry React Native SDK
|
|
2
|
+
|
|
3
|
+
> **Minimum SDK:** `@sentry/react-native` ≥ 5.20.0 for TTID/TTFD · ≥ 5.32.0 for
|
|
4
|
+
> profiling · ≥ 8.0.0 recommended **Mobile-first note:** React Native has unique
|
|
5
|
+
> performance capabilities web SDKs don’t provide — cold/warm app start tracking, JS
|
|
6
|
+
> event loop stall detection, slow/frozen frame counting, and navigation-based
|
|
7
|
+
> transactions. All are first-class citizens in the Sentry RN SDK.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
1. [Basic Tracing Setup](#1-basic-tracing-setup)
|
|
14
|
+
2. [Automatic Instrumentation Setup](#2-automatic-instrumentation-setup)
|
|
15
|
+
3. [App Start Tracing](#3-app-start-tracing)
|
|
16
|
+
4. [Navigation Instrumentation](#4-navigation-instrumentation)
|
|
17
|
+
5. [Screen Rendering: Time to Display](#5-screen-rendering-time-to-display)
|
|
18
|
+
6. [Slow & Frozen Frames](#6-slow--frozen-frames)
|
|
19
|
+
7. [Stall Tracking](#7-stall-tracking)
|
|
20
|
+
8. [Network Request Tracing](#8-network-request-tracing)
|
|
21
|
+
9. [Distributed Tracing](#9-distributed-tracing)
|
|
22
|
+
10. [User Interaction Tracing](#10-user-interaction-tracing)
|
|
23
|
+
11. [Custom Spans](#11-custom-spans)
|
|
24
|
+
12. [React Component Profiler](#12-react-component-profiler)
|
|
25
|
+
13. [Profiling (Native + Hermes)](#13-profiling-native--hermes)
|
|
26
|
+
14. [Dynamic Sampling](#14-dynamic-sampling)
|
|
27
|
+
15. [Configuration Reference](#15-configuration-reference)
|
|
28
|
+
16. [Mobile vs Web: Feature Matrix](#16-mobile-vs-web-feature-matrix)
|
|
29
|
+
17. [Troubleshooting](#17-troubleshooting)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 1. Basic Tracing Setup
|
|
34
|
+
|
|
35
|
+
Tracing requires **no additional imports** beyond the standard Sentry import — a key
|
|
36
|
+
difference from the web SDK.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import * as Sentry from "@sentry/react-native";
|
|
40
|
+
|
|
41
|
+
Sentry.init({
|
|
42
|
+
dsn: "YOUR_DSN",
|
|
43
|
+
|
|
44
|
+
// Option A: uniform sample rate (0.0–1.0)
|
|
45
|
+
// 1.0 = 100% of transactions captured — development/testing only
|
|
46
|
+
tracesSampleRate: 1.0,
|
|
47
|
+
|
|
48
|
+
// Option B: dynamic sampler — takes precedence over tracesSampleRate when both are set
|
|
49
|
+
// tracesSampler: ({ name, attributes, parentSampled }) => {
|
|
50
|
+
// if (name === "checkout") return 1.0;
|
|
51
|
+
// return 0.2;
|
|
52
|
+
// },
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> **Production recommendation:** Use `tracesSampleRate: 0.2` or lower, or switch to
|
|
57
|
+
> `tracesSampler` for context-aware sampling.
|
|
58
|
+
> 100% sampling causes high volume at scale.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 2. Automatic Instrumentation Setup
|
|
63
|
+
|
|
64
|
+
`reactNativeTracingIntegration` must be explicitly added to enable automatic tracing
|
|
65
|
+
features. Two required setup steps:
|
|
66
|
+
|
|
67
|
+
### Step 1 — Add the integration
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import * as Sentry from "@sentry/react-native";
|
|
71
|
+
|
|
72
|
+
Sentry.init({
|
|
73
|
+
dsn: "YOUR_DSN",
|
|
74
|
+
tracesSampleRate: 1.0,
|
|
75
|
+
integrations: [Sentry.reactNativeTracingIntegration()],
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Step 2 — Wrap your root component
|
|
80
|
+
|
|
81
|
+
Required for accurate App Start measurement (records to first component mount instead of
|
|
82
|
+
JS initialization) and to enable User Interaction tracing:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// App.tsx
|
|
86
|
+
export default Sentry.wrap(App);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Opt out of automatic instrumentation
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
Sentry.init({
|
|
93
|
+
dsn: "YOUR_DSN",
|
|
94
|
+
enableAutoPerformanceTracing: false, // disables all auto instrumentation
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 3. App Start Tracing
|
|
101
|
+
|
|
102
|
+
**Unique to mobile.** Tracks the duration from the earliest native process
|
|
103
|
+
initialization to React Native root component mount.
|
|
104
|
+
|
|
105
|
+
| Metric | Measurement Key | When it fires |
|
|
106
|
+
| -------------- | ----------------------------- | ------------------------------------------------- |
|
|
107
|
+
| **Cold start** | `measurements.app_start_cold` | Process launched from scratch (not in memory) |
|
|
108
|
+
| **Warm start** | `measurements.app_start_warm` | Process was already in memory, activity recreated |
|
|
109
|
+
|
|
110
|
+
> **Hot starts and resumes are not tracked.** They’re considered too fast to be
|
|
111
|
+
> meaningful for monitoring.
|
|
112
|
+
|
|
113
|
+
### Why `Sentry.wrap(App)` matters for App Start
|
|
114
|
+
|
|
115
|
+
Without `Sentry.wrap(App)`, the App Start measurement ends at JS initialization rather
|
|
116
|
+
than at first component mount.
|
|
117
|
+
Wrapping is essential for accurate data that represents the real user experience.
|
|
118
|
+
|
|
119
|
+
### How App Start appears in traces
|
|
120
|
+
|
|
121
|
+
When a routing integration (React Navigation, Expo Router, RNN) is present, App Start
|
|
122
|
+
data appears as **spans inside the first navigation transaction** — not as a standalone
|
|
123
|
+
transaction. You’ll see it in the trace waterfall as a child span at the root of the
|
|
124
|
+
first screen.
|
|
125
|
+
|
|
126
|
+
### Platform accuracy notes
|
|
127
|
+
|
|
128
|
+
Sentry follows Apple and Google’s official App Start guidelines.
|
|
129
|
+
Reported values may be slightly longer than other tools, as they’re designed to most
|
|
130
|
+
accurately represent real user experience rather than minimize measured time.
|
|
131
|
+
|
|
132
|
+
### Optimizing App Start time
|
|
133
|
+
|
|
134
|
+
Common causes of slow cold starts and how to address them:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// ❌ Eager import — executes at bundle parse time
|
|
138
|
+
import { HeavyModule } from "./heavy-module";
|
|
139
|
+
|
|
140
|
+
// ✅ Lazy import — deferred until actually needed
|
|
141
|
+
const loadHeavy = () => import("./heavy-module");
|
|
142
|
+
|
|
143
|
+
// ❌ Synchronous AsyncStorage read at startup
|
|
144
|
+
const theme = await AsyncStorage.getItem("theme"); // blocks JS thread
|
|
145
|
+
|
|
146
|
+
// ✅ Use a synchronous-safe default, hydrate later
|
|
147
|
+
const [theme, setTheme] = useState("light");
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
AsyncStorage.getItem("theme").then(setTheme);
|
|
150
|
+
}, []);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 4. Navigation Instrumentation
|
|
156
|
+
|
|
157
|
+
The routing integration determines how navigation events create transactions.
|
|
158
|
+
Each screen transition becomes a transaction, with the screen name as the transaction
|
|
159
|
+
name.
|
|
160
|
+
|
|
161
|
+
### 4a. React Navigation (v5+)
|
|
162
|
+
|
|
163
|
+
The most common setup.
|
|
164
|
+
Creates a transaction for every route change automatically.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
import * as Sentry from "@sentry/react-native";
|
|
168
|
+
import {
|
|
169
|
+
NavigationContainer,
|
|
170
|
+
createNavigationContainerRef,
|
|
171
|
+
} from "@react-navigation/native";
|
|
172
|
+
|
|
173
|
+
// Step 1 — Create the integration BEFORE Sentry.init
|
|
174
|
+
const navigationIntegration = Sentry.reactNavigationIntegration({
|
|
175
|
+
enableTimeToInitialDisplay: true, // enable TTID measurement per screen
|
|
176
|
+
routeChangeTimeoutMs: 1_000, // discard transaction if screen doesn't mount within 1s
|
|
177
|
+
ignoreEmptyBackNavigationTransactions: true, // drop back-nav transactions with no child spans
|
|
178
|
+
useDispatchedActionData: true, // attach action data to transaction metadata
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Step 2 — Pass to Sentry.init
|
|
182
|
+
Sentry.init({
|
|
183
|
+
dsn: "YOUR_DSN",
|
|
184
|
+
tracesSampleRate: 1.0,
|
|
185
|
+
integrations: [navigationIntegration],
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Step 3 — Register the container ref in onReady
|
|
189
|
+
function App() {
|
|
190
|
+
const containerRef = createNavigationContainerRef();
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<NavigationContainer
|
|
194
|
+
ref={containerRef}
|
|
195
|
+
onReady={() => {
|
|
196
|
+
// Must be called inside onReady — not before the container is ready
|
|
197
|
+
navigationIntegration.registerNavigationContainer(containerRef);
|
|
198
|
+
}}
|
|
199
|
+
>
|
|
200
|
+
{/* screens */}
|
|
201
|
+
</NavigationContainer>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export default Sentry.wrap(App);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### 4b. React Native Navigation (Wix/RNN)
|
|
209
|
+
|
|
210
|
+
Pass the `Navigation` object directly — no ref or container wrapping needed.
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import * as Sentry from "@sentry/react-native";
|
|
214
|
+
import { Navigation } from "react-native-navigation";
|
|
215
|
+
|
|
216
|
+
Sentry.init({
|
|
217
|
+
dsn: "YOUR_DSN",
|
|
218
|
+
tracesSampleRate: 1.0,
|
|
219
|
+
integrations: [
|
|
220
|
+
Sentry.reactNativeNavigationIntegration({
|
|
221
|
+
navigation: Navigation, // required — the RNN Navigation object
|
|
222
|
+
routeChangeTimeoutMs: 1_000, // discard stale transactions
|
|
223
|
+
enableTabsInstrumentation: true, // create transactions on tab changes (default: false)
|
|
224
|
+
ignoreEmptyBackNavigationTransactions: true, // drop no-span back navigations
|
|
225
|
+
}),
|
|
226
|
+
],
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Customizing transaction names
|
|
231
|
+
|
|
232
|
+
Transaction names default to the route/screen name (e.g., `LoginScreen`, `HomeTab`).
|
|
233
|
+
Modify via `beforeStartSpan`:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
Sentry.reactNativeTracingIntegration({
|
|
237
|
+
beforeStartSpan: (context) => ({
|
|
238
|
+
...context,
|
|
239
|
+
name: context.name.replace("Screen", ""), // strip "Screen" suffix for cleaner names
|
|
240
|
+
attributes: {
|
|
241
|
+
...context.attributes,
|
|
242
|
+
"app.version": "2.1.0",
|
|
243
|
+
},
|
|
244
|
+
}),
|
|
245
|
+
}),
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Tab navigation
|
|
249
|
+
|
|
250
|
+
Tab navigators preload screens, so auto-instrumentation only creates a transaction for
|
|
251
|
+
the **initial** tab visit.
|
|
252
|
+
For subsequent tab switches, use the `TimeToInitialDisplay` and `TimeToFullDisplay`
|
|
253
|
+
components explicitly (see §5).
|
|
254
|
+
|
|
255
|
+
### 4c. Expo Router Dynamic Route Params as Span Attributes
|
|
256
|
+
|
|
257
|
+
When using Expo Router with dynamic route segments (e.g., `profile/[id]`,
|
|
258
|
+
`posts/[...slug]`), the SDK automatically captures the dynamic parameter values as span
|
|
259
|
+
attributes on navigation transactions.
|
|
260
|
+
|
|
261
|
+
**Requirements:**
|
|
262
|
+
|
|
263
|
+
- `sendDefaultPii: true` must be set in `Sentry.init` — these values are
|
|
264
|
+
user-identifiable
|
|
265
|
+
- Route names must use Expo Router bracket notation: `[param]` or `[...param]`
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
Sentry.init({
|
|
269
|
+
dsn: "YOUR_DSN",
|
|
270
|
+
tracesSampleRate: 1.0,
|
|
271
|
+
sendDefaultPii: true, // required — route param values may identify users
|
|
272
|
+
|
|
273
|
+
integrations: [navigationIntegration],
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
When navigating to a route like `profile/[id]` with params `{ id: '123' }`, the
|
|
278
|
+
navigation span receives:
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
route.name → "profile/[id]"
|
|
282
|
+
route.params.id → "123"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
For catch-all segments (`[...slug]`), array values are joined with `/`:
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
route.name → "posts/[...slug]"
|
|
289
|
+
route.params.slug → "tech/react-native"
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Only structural params are captured** — query params and extra props that don’t match
|
|
293
|
+
a dynamic segment in the route name are intentionally excluded.
|
|
294
|
+
This prevents non-structural data (referrers, UTM parameters, etc.)
|
|
295
|
+
from being captured as trace attributes.
|
|
296
|
+
|
|
297
|
+
| Scenario | Captured? |
|
|
298
|
+
| ------------------------------------------------- | ---------------------------------------- |
|
|
299
|
+
| `profile/[id]` with `{ id: '123' }` | ✅ `route.params.id = "123"` |
|
|
300
|
+
| `posts/[...slug]` with `{ slug: ['tech', 'rn'] }` | ✅ `route.params.slug = "tech/rn"` |
|
|
301
|
+
| `StaticScreen` with `{ utm_source: 'email' }` | ❌ No dynamic segment — nothing captured |
|
|
302
|
+
| Any route with `sendDefaultPii: false` | ❌ Opted out — nothing captured |
|
|
303
|
+
|
|
304
|
+
> **Privacy note:** Dynamic route param values (e.g., the `123` in `profile/[id]`) are
|
|
305
|
+
> user-identifiable. They are only captured when `sendDefaultPii: true` is explicitly
|
|
306
|
+
> set. Review your routes to ensure no sensitive values (tokens, PII) appear in path
|
|
307
|
+
> segments before enabling this option.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 5. Screen Rendering: Time to Display
|
|
312
|
+
|
|
313
|
+
Two **Mobile Vitals** that have no web equivalent:
|
|
314
|
+
|
|
315
|
+
| Metric | Abbreviation | What it measures |
|
|
316
|
+
| --------------------------- | ------------ | ------------------------------------------------------------------------------- |
|
|
317
|
+
| **Time to Initial Display** | TTID | From navigation event → first rendered frame visible after Screen mounts |
|
|
318
|
+
| **Time to Full Display** | TTFD | From navigation event → all async content loaded and ready for user interaction |
|
|
319
|
+
|
|
320
|
+
> **Requirements:** SDK ≥ `5.20.0` · Native build required (not available in Expo Go)
|
|
321
|
+
|
|
322
|
+
### Automatic TTID (React Navigation only)
|
|
323
|
+
|
|
324
|
+
Enable in the integration config.
|
|
325
|
+
TTID spans automatically include animation completion time (except JS-driven animations
|
|
326
|
+
on iOS, which are excluded).
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
const navigationIntegration = Sentry.reactNavigationIntegration({
|
|
330
|
+
enableTimeToInitialDisplay: true, // that's it
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Manual TTID override
|
|
335
|
+
|
|
336
|
+
Use when you need to control exactly when “initial display” is considered complete:
|
|
337
|
+
|
|
338
|
+
```tsx
|
|
339
|
+
import * as Sentry from "@sentry/react-native";
|
|
340
|
+
import { View } from "react-native";
|
|
341
|
+
|
|
342
|
+
function ProductListScreen() {
|
|
343
|
+
return (
|
|
344
|
+
<View>
|
|
345
|
+
<Sentry.TimeToInitialDisplay record={true} />
|
|
346
|
+
{/* content */}
|
|
347
|
+
</View>
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Time to Full Display (TTFD)
|
|
353
|
+
|
|
354
|
+
Mark full display when all async content is loaded.
|
|
355
|
+
The `record` prop fires once when it transitions from `false` to `true`:
|
|
356
|
+
|
|
357
|
+
```tsx
|
|
358
|
+
import * as Sentry from "@sentry/react-native";
|
|
359
|
+
import { useState, useEffect } from "react";
|
|
360
|
+
import { View, Text, ActivityIndicator } from "react-native";
|
|
361
|
+
|
|
362
|
+
function ProductDetailScreen({ productId }: { productId: string }) {
|
|
363
|
+
const [product, setProduct] = useState<Product | null>(null);
|
|
364
|
+
|
|
365
|
+
useEffect(() => {
|
|
366
|
+
fetch(`https://api.example.com/products/${productId}`)
|
|
367
|
+
.then((res) => res.json())
|
|
368
|
+
.then(setProduct);
|
|
369
|
+
}, [productId]);
|
|
370
|
+
|
|
371
|
+
return (
|
|
372
|
+
<View>
|
|
373
|
+
{/* Fires once when product transitions from null to loaded */}
|
|
374
|
+
<Sentry.TimeToFullDisplay record={product !== null} />
|
|
375
|
+
|
|
376
|
+
{product ? <Text>{product.name}</Text> : <ActivityIndicator />}
|
|
377
|
+
</View>
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Tab screens — explicit TTID + TTFD
|
|
383
|
+
|
|
384
|
+
Because tab screens are preloaded, auto-detection only fires on the first visit.
|
|
385
|
+
Add both components explicitly for every tab screen:
|
|
386
|
+
|
|
387
|
+
```tsx
|
|
388
|
+
function HomeTabScreen({ isLoading }: { isLoading: boolean }) {
|
|
389
|
+
return (
|
|
390
|
+
<View>
|
|
391
|
+
<Sentry.TimeToInitialDisplay record={true} />
|
|
392
|
+
<Sentry.TimeToFullDisplay record={!isLoading} />
|
|
393
|
+
{/* content */}
|
|
394
|
+
</View>
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
> Both `<TimeToInitialDisplay />` and `<TimeToFullDisplay />` render as `<></>` — **zero
|
|
400
|
+
> visual impact.**
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## 6. Slow & Frozen Frames
|
|
405
|
+
|
|
406
|
+
**Mobile Vitals** — automatically captured per transaction when tracing is enabled.
|
|
407
|
+
No configuration required.
|
|
408
|
+
|
|
409
|
+
| Frame type | Threshold | User experience |
|
|
410
|
+
| ---------------- | ----------------------------------------------- | -------------------------- |
|
|
411
|
+
| **Slow frame** | Takes longer than expected for the refresh rate | UI hitches, animation jank |
|
|
412
|
+
| **Frozen frame** | Completely unresponsive | App appears hung |
|
|
413
|
+
|
|
414
|
+
> Web Vitals (LCP, FID, CLS) are **not** reported for React Native — slow/frozen frames
|
|
415
|
+
> are the mobile equivalent.
|
|
416
|
+
|
|
417
|
+
These appear in the **Mobile Vitals** section of every transaction in Sentry’s
|
|
418
|
+
performance UI, alongside App Start time.
|
|
419
|
+
|
|
420
|
+
### Android: AndroidX dependency
|
|
421
|
+
|
|
422
|
+
Sentry uses `androidx.core` for accurate slow/frozen frame detection across all Android
|
|
423
|
+
versions. It’s included automatically.
|
|
424
|
+
If you explicitly remove it:
|
|
425
|
+
|
|
426
|
+
```groovy
|
|
427
|
+
// android/app/build.gradle — removes androidx.core AND disables frame reporting
|
|
428
|
+
api('io.sentry:sentry-android:8.33.0') {
|
|
429
|
+
exclude group: 'androidx.core', module: 'core'
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
> **Warning:** Removing `androidx.core` disables slow/frozen frame detection entirely.
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
## 7. Stall Tracking
|
|
438
|
+
|
|
439
|
+
**Unique to React Native.** A “stall” is when the JavaScript event loop takes longer
|
|
440
|
+
than expected to process a tick — it directly blocks UI rendering and all JS logic.
|
|
441
|
+
|
|
442
|
+
Three metrics automatically attached to every transaction:
|
|
443
|
+
|
|
444
|
+
| Metric | Description |
|
|
445
|
+
| ---------------------- | ---------------------------------------------------- |
|
|
446
|
+
| **Longest Stall Time** | Duration (ms) of the single longest event loop stall |
|
|
447
|
+
| **Total Stall Time** | Combined ms of all stalls during the transaction |
|
|
448
|
+
| **Stall Count** | Number of individual stalls |
|
|
449
|
+
|
|
450
|
+
No configuration needed — stall tracking is enabled automatically by
|
|
451
|
+
`reactNativeTracingIntegration`.
|
|
452
|
+
|
|
453
|
+
### What causes stalls
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
// ❌ Synchronous heavy computation on the JS thread — causes stalls
|
|
457
|
+
const result = items.reduce((acc, item) => {
|
|
458
|
+
return acc + expensiveComputation(item); // blocks JS thread
|
|
459
|
+
}, 0);
|
|
460
|
+
|
|
461
|
+
// ✅ Offload to InteractionManager or requestAnimationFrame
|
|
462
|
+
InteractionManager.runAfterInteractions(() => {
|
|
463
|
+
const result = items.reduce((acc, item) => {
|
|
464
|
+
return acc + expensiveComputation(item);
|
|
465
|
+
}, 0);
|
|
466
|
+
setState(result);
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
// ✅ Or better — move to a native module / worklet (Reanimated)
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## 8. Network Request Tracing
|
|
475
|
+
|
|
476
|
+
Every `fetch` and `XMLHttpRequest` call made while a transaction is active automatically
|
|
477
|
+
gets a child span. No code changes needed.
|
|
478
|
+
|
|
479
|
+
Span data includes:
|
|
480
|
+
|
|
481
|
+
- HTTP method and URL
|
|
482
|
+
- Response status code
|
|
483
|
+
- Request/response size
|
|
484
|
+
- Duration (time-to-first-byte + total)
|
|
485
|
+
|
|
486
|
+
### Filter which requests get spans
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
Sentry.reactNativeTracingIntegration({
|
|
490
|
+
shouldCreateSpanForRequest: (url) => {
|
|
491
|
+
// Skip analytics pings and health checks
|
|
492
|
+
return !url.match(/\/(analytics|health|metrics)\/?(\?.*)?$/);
|
|
493
|
+
},
|
|
494
|
+
}),
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Transaction idle and final timeouts
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
Sentry.reactNativeTracingIntegration({
|
|
501
|
+
idleTimeoutMs: 1_000, // end transaction after 1s of inactivity (default: 1000)
|
|
502
|
+
finalTimeoutMs: 600_000, // hard cap: 10 minutes max transaction duration (default: 600000)
|
|
503
|
+
}),
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## 9. Distributed Tracing
|
|
509
|
+
|
|
510
|
+
Connects mobile traces to backend traces so you can see the full request lifecycle —
|
|
511
|
+
from the user’s tap to database query and back.
|
|
512
|
+
|
|
513
|
+
### How it works
|
|
514
|
+
|
|
515
|
+
When a `fetch` request fires inside a transaction, the SDK attaches two headers:
|
|
516
|
+
|
|
517
|
+
| Header | Purpose |
|
|
518
|
+
| -------------- | -------------------------------------------- |
|
|
519
|
+
| `sentry-trace` | Carries the trace ID and span ID |
|
|
520
|
+
| `baggage` | Carries sampling decision and trace metadata |
|
|
521
|
+
|
|
522
|
+
Your backend Sentry SDK reads these headers and links its spans to the same trace, so
|
|
523
|
+
you see one unified waterfall in Sentry.
|
|
524
|
+
|
|
525
|
+
### `tracePropagationTargets` — control where headers attach
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
Sentry.init({
|
|
529
|
+
dsn: "YOUR_DSN",
|
|
530
|
+
tracesSampleRate: 1.0,
|
|
531
|
+
|
|
532
|
+
// Default on mobile: [/.*/] — attaches to ALL outgoing requests
|
|
533
|
+
// Restrict to your own APIs:
|
|
534
|
+
tracePropagationTargets: [
|
|
535
|
+
"api.myapp.com", // string — matched against the full URL
|
|
536
|
+
/^https:\/\/api\./, // regex — matched against the full URL
|
|
537
|
+
"localhost", // useful for local development
|
|
538
|
+
],
|
|
539
|
+
});
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
> **Important:** `tracePropagationTargets` matches against the **entire URL string**,
|
|
543
|
+
> not just the domain.
|
|
544
|
+
|
|
545
|
+
### CORS requirements for web APIs
|
|
546
|
+
|
|
547
|
+
If your React Native app calls web APIs that run CORS preflight checks, the backend must
|
|
548
|
+
allow the Sentry headers:
|
|
549
|
+
|
|
550
|
+
```
|
|
551
|
+
Access-Control-Allow-Headers: sentry-trace, baggage
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Without this, browsers (and React Native on web) will reject the preflight and the
|
|
555
|
+
request will fail.
|
|
556
|
+
|
|
557
|
+
### End-to-end example: RN → Node.js API
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
// React Native — starts the trace
|
|
561
|
+
await Sentry.startSpan({ name: "addToCart", op: "ui.action" }, async () => {
|
|
562
|
+
// This fetch will carry sentry-trace + baggage headers to api.myapp.com
|
|
563
|
+
const response = await fetch("https://api.myapp.com/cart/items", {
|
|
564
|
+
method: "POST",
|
|
565
|
+
body: JSON.stringify({ productId: "abc-123" }),
|
|
566
|
+
});
|
|
567
|
+
return response.json();
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
// Node.js backend (with @sentry/node) — automatically continues the trace
|
|
571
|
+
// The backend span appears as a child in the same trace waterfall
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
```python
|
|
575
|
+
# Python backend (with sentry-sdk) — also continues the trace automatically
|
|
576
|
+
# No extra code needed beyond standard Sentry initialization
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## 10. User Interaction Tracing
|
|
582
|
+
|
|
583
|
+
Captures transactions and breadcrumbs for touch events.
|
|
584
|
+
Transaction names are automatically composed as `ScreenName > element_label`.
|
|
585
|
+
|
|
586
|
+
### Enable
|
|
587
|
+
|
|
588
|
+
```typescript
|
|
589
|
+
Sentry.init({
|
|
590
|
+
dsn: "YOUR_DSN",
|
|
591
|
+
enableUserInteractionTracing: true, // disabled by default
|
|
592
|
+
tracesSampleRate: 1.0,
|
|
593
|
+
integrations: [navigationIntegration],
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
// Wrapping is required for interaction tracing to work
|
|
597
|
+
export default Sentry.wrap(App);
|
|
598
|
+
|
|
599
|
+
// Or with a custom label prop name:
|
|
600
|
+
export default Sentry.wrap(App, {
|
|
601
|
+
touchEventBoundaryProps: { labelName: "tracking-id" }, // defaults to "sentry-label"
|
|
602
|
+
});
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### Label interactive elements
|
|
606
|
+
|
|
607
|
+
```tsx
|
|
608
|
+
// Without a label, no transaction is created — the tap is silently ignored
|
|
609
|
+
<Pressable
|
|
610
|
+
sentry-label="add_to_cart_button"
|
|
611
|
+
onPress={handleAddToCart}
|
|
612
|
+
>
|
|
613
|
+
<Text>Add to Cart</Text>
|
|
614
|
+
</Pressable>
|
|
615
|
+
|
|
616
|
+
// Also works on TouchableOpacity, TouchableHighlight, etc.
|
|
617
|
+
<TouchableOpacity sentry-label="checkout_button" onPress={handleCheckout}>
|
|
618
|
+
<Text>Checkout</Text>
|
|
619
|
+
</TouchableOpacity>
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
> Transactions with no child spans are automatically dropped — only meaningful
|
|
623
|
+
> interactions are recorded.
|
|
624
|
+
|
|
625
|
+
### Custom span attributes on interactions (experimental)
|
|
626
|
+
|
|
627
|
+
```tsx
|
|
628
|
+
<Pressable
|
|
629
|
+
sentry-label="checkout"
|
|
630
|
+
sentry-span-attributes={{
|
|
631
|
+
"user.plan": userPlan, // string
|
|
632
|
+
"cart.item_count": itemCount, // number
|
|
633
|
+
"cart.has_coupon": hasCoupon, // boolean
|
|
634
|
+
}}
|
|
635
|
+
onPress={handleCheckout}
|
|
636
|
+
>
|
|
637
|
+
<Text>Checkout</Text>
|
|
638
|
+
</Pressable>
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
> `sentry-span-attributes` is **experimental** — API may change.
|
|
642
|
+
> The SDK traverses the component tree to find it, so it can be placed on a parent
|
|
643
|
+
> element.
|
|
644
|
+
|
|
645
|
+
### Gesture Handler (RNGH v2)
|
|
646
|
+
|
|
647
|
+
```tsx
|
|
648
|
+
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
649
|
+
import { sentryTraceGesture } from "@sentry/react-native";
|
|
650
|
+
|
|
651
|
+
function ZoomableImage() {
|
|
652
|
+
const pinch = Gesture.Pinch();
|
|
653
|
+
const longPress = Gesture.LongPress();
|
|
654
|
+
|
|
655
|
+
const gesture = Gesture.Race(
|
|
656
|
+
sentryTraceGesture("pinch-to-zoom", pinch), // label must be unique per screen
|
|
657
|
+
sentryTraceGesture("long-press-cancel", longPress),
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
return (
|
|
661
|
+
<GestureDetector gesture={gesture}>
|
|
662
|
+
<Image source={imageSource} />
|
|
663
|
+
</GestureDetector>
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
> Only RNGH **API v2** is supported.
|
|
669
|
+
> Both transactions and breadcrumbs are created automatically.
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
## 11. Custom Spans
|
|
674
|
+
|
|
675
|
+
```typescript
|
|
676
|
+
import * as Sentry from "@sentry/react-native";
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
### `startSpan` — Active, auto-ending (recommended)
|
|
680
|
+
|
|
681
|
+
The span becomes the active parent for any child spans created inside the callback.
|
|
682
|
+
Ends automatically when the callback resolves (sync or async).
|
|
683
|
+
|
|
684
|
+
```typescript
|
|
685
|
+
// Synchronous
|
|
686
|
+
const total = Sentry.startSpan({ name: "computeCartTotal", op: "function" }, () => {
|
|
687
|
+
return items.reduce((sum, item) => sum + item.price, 0);
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
// Async
|
|
691
|
+
const data = await Sentry.startSpan({ name: "fetchUserProfile", op: "http.client" }, async () => {
|
|
692
|
+
const res = await fetch("https://api.example.com/profile");
|
|
693
|
+
return res.json();
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
// Nested — child spans automatically attach to their enclosing parent
|
|
697
|
+
await Sentry.startSpan({ name: "checkout", op: "function" }, async () => {
|
|
698
|
+
await Sentry.startSpan({ name: "validateCart", op: "function" }, validateCart);
|
|
699
|
+
await Sentry.startSpan({ name: "processPayment", op: "function" }, processPayment);
|
|
700
|
+
await Sentry.startSpan({ name: "sendConfirmation", op: "http.client" }, sendEmail);
|
|
701
|
+
});
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### `startSpanManual` — Active, manually ended
|
|
705
|
+
|
|
706
|
+
Use when the span lifetime doesn’t map cleanly to a function scope (e.g., spans across
|
|
707
|
+
event callbacks):
|
|
708
|
+
|
|
709
|
+
```typescript
|
|
710
|
+
function trackAnimationPerformance() {
|
|
711
|
+
return Sentry.startSpanManual({ name: "heroAnimation", op: "ui.render" }, (span) => {
|
|
712
|
+
const animation = Animated.timing(translateY, {
|
|
713
|
+
toValue: 0,
|
|
714
|
+
duration: 300,
|
|
715
|
+
useNativeDriver: true,
|
|
716
|
+
});
|
|
717
|
+
animation.start(({ finished }) => {
|
|
718
|
+
span.setAttribute("animation.completed", finished);
|
|
719
|
+
span.end(); // must call end() manually
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### `startInactiveSpan` — Inactive, manually ended
|
|
726
|
+
|
|
727
|
+
Inactive spans never become automatic parents for child spans.
|
|
728
|
+
Use for fire-and-forget measurements:
|
|
729
|
+
|
|
730
|
+
```typescript
|
|
731
|
+
// Start a background sync span without it affecting the current active span
|
|
732
|
+
const syncSpan = Sentry.startInactiveSpan({ name: "backgroundSync", op: "function" });
|
|
733
|
+
|
|
734
|
+
await syncLocalDatabase();
|
|
735
|
+
|
|
736
|
+
syncSpan.end();
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
### Span options
|
|
740
|
+
|
|
741
|
+
| Option | Type | Description |
|
|
742
|
+
| ------------------ | ------------------------------------------------------ | ---------------------------------------------------------------- |
|
|
743
|
+
| `name` | `string` | **Required.** Display name in Sentry UI |
|
|
744
|
+
| `op` | `string` | Operation type — use standard values for enhanced UI (see below) |
|
|
745
|
+
| `attributes` | `Record<string, string \| number \| boolean \| array>` | Key/value metadata attached to the span |
|
|
746
|
+
| `startTime` | `number` | Custom start timestamp (Unix epoch, seconds) |
|
|
747
|
+
| `parentSpan` | `Span` | Explicit parent — overrides the active span |
|
|
748
|
+
| `onlyIfParent` | `boolean` | Skip this span if there’s no active parent |
|
|
749
|
+
| `forceTransaction` | `boolean` | Force the span to appear as a top-level transaction in the UI |
|
|
750
|
+
|
|
751
|
+
### Standard operation types for mobile
|
|
752
|
+
|
|
753
|
+
Using well-known `op` values unlocks enhanced Sentry UI features (grouping, filtering,
|
|
754
|
+
icons):
|
|
755
|
+
|
|
756
|
+
```typescript
|
|
757
|
+
Sentry.startSpan({ name: "GET /api/products", op: "http.client" }, fetchProducts);
|
|
758
|
+
Sentry.startSpan({ name: "SELECT * FROM users", op: "db" }, queryDatabase);
|
|
759
|
+
Sentry.startSpan({ name: "parseProductData", op: "function" }, parseData);
|
|
760
|
+
Sentry.startSpan({ name: "HomeScreen render", op: "ui.render" }, render);
|
|
761
|
+
Sentry.startSpan({ name: "readProductsCache", op: "file.read" }, readCache);
|
|
762
|
+
Sentry.startSpan({ name: "writeOrdersCache", op: "file.write" }, writeCache);
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
Full operation list:
|
|
766
|
+
[develop.sentry.dev/sdk/performance/span-operations](https://develop.sentry.dev/sdk/performance/span-operations/#list-of-operations)
|
|
767
|
+
|
|
768
|
+
### Adding attributes
|
|
769
|
+
|
|
770
|
+
```typescript
|
|
771
|
+
// At creation time
|
|
772
|
+
await Sentry.startSpan(
|
|
773
|
+
{
|
|
774
|
+
name: "loadFeed",
|
|
775
|
+
op: "http.client",
|
|
776
|
+
attributes: {
|
|
777
|
+
"feed.type": "following",
|
|
778
|
+
"feed.page": 1,
|
|
779
|
+
"feed.has_cache": false,
|
|
780
|
+
},
|
|
781
|
+
},
|
|
782
|
+
loadFeed,
|
|
783
|
+
);
|
|
784
|
+
|
|
785
|
+
// On an existing span
|
|
786
|
+
const span = Sentry.getActiveSpan();
|
|
787
|
+
if (span) {
|
|
788
|
+
span.setAttribute("result.count", 42);
|
|
789
|
+
span.setAttributes({ "filter.applied": true, "filter.type": "category" });
|
|
790
|
+
span.updateName("loadFeed:following"); // rename mid-flight
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### Span utilities
|
|
795
|
+
|
|
796
|
+
```typescript
|
|
797
|
+
// Get the currently active span
|
|
798
|
+
const activeSpan = Sentry.getActiveSpan();
|
|
799
|
+
|
|
800
|
+
// Get the root span (the transaction) from any span
|
|
801
|
+
const rootSpan = activeSpan ? Sentry.getRootSpan(activeSpan) : undefined;
|
|
802
|
+
|
|
803
|
+
// Explicitly set a span as the active parent for a block
|
|
804
|
+
const parent = Sentry.startInactiveSpan({ name: "parent" });
|
|
805
|
+
Sentry.withActiveSpan(parent, () => {
|
|
806
|
+
Sentry.startSpan({ name: "child" }, () => {
|
|
807
|
+
/* child attaches to parent */
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
// Create a root-level span regardless of current context
|
|
812
|
+
Sentry.withActiveSpan(null, () => {
|
|
813
|
+
Sentry.startSpan({ name: "isolated" }, () => {
|
|
814
|
+
/* no parent */
|
|
815
|
+
});
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
// Prevent a specific operation from creating spans
|
|
819
|
+
Sentry.suppressTracing(() => {
|
|
820
|
+
fetch("https://analytics.internal/ping"); // no span created for this request
|
|
821
|
+
});
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
### Span hierarchy: flat vs. nested
|
|
825
|
+
|
|
826
|
+
By default (mobile and browser environments), all spans are flat children of the root
|
|
827
|
+
transaction to avoid async parent misattribution:
|
|
828
|
+
|
|
829
|
+
```typescript
|
|
830
|
+
// Default behavior — both fetches become siblings under the root, not children of their span
|
|
831
|
+
await Sentry.startSpan({ name: "span1" }, async () => {
|
|
832
|
+
await fetch("https://api.example.com/a"); // child of root transaction
|
|
833
|
+
});
|
|
834
|
+
await Sentry.startSpan({ name: "span2" }, async () => {
|
|
835
|
+
await fetch("https://api.example.com/b"); // child of root transaction
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
// Opt into full nesting (may cause incorrect parent attribution with async/await)
|
|
839
|
+
Sentry.init({ parentSpanIsAlwaysRootSpan: false });
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
---
|
|
843
|
+
|
|
844
|
+
## 12. React Component Profiler
|
|
845
|
+
|
|
846
|
+
Track individual React component lifecycle (mount, update, unmount) as child spans
|
|
847
|
+
within the current route transaction.
|
|
848
|
+
Useful for identifying slow renders and unnecessary re-renders.
|
|
849
|
+
|
|
850
|
+
```typescript
|
|
851
|
+
import * as Sentry from "@sentry/react-native";
|
|
852
|
+
|
|
853
|
+
// Wrap any component with withProfiler
|
|
854
|
+
const ProductCard = Sentry.withProfiler(({ product }) => {
|
|
855
|
+
return <View>{/* component content */}</View>;
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
// Or wrap the export
|
|
859
|
+
export default Sentry.withProfiler(HeavyListScreen);
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
Profiler spans show up in the transaction waterfall under `ui.react.render` and
|
|
863
|
+
`ui.react.update` operations.
|
|
864
|
+
|
|
865
|
+
> **Production builds warning:** React Native minifies class/function names in
|
|
866
|
+
> production. Configure the Sentry Gradle/Xcode plugin + source maps to preserve
|
|
867
|
+
> component names in production profiler data.
|
|
868
|
+
> See the SDK
|
|
869
|
+
> [source maps guide](https://docs.sentry.io/platforms/react-native/sourcemaps/).
|
|
870
|
+
|
|
871
|
+
---
|
|
872
|
+
|
|
873
|
+
## 13. Profiling (Native + Hermes)
|
|
874
|
+
|
|
875
|
+
Profiling samples the call stack at regular intervals to surface hot code paths.
|
|
876
|
+
Requires tracing to be enabled first — only traced transactions are profiled.
|
|
877
|
+
|
|
878
|
+
**Minimum SDK version:** `5.32.0`
|
|
879
|
+
|
|
880
|
+
### Basic setup
|
|
881
|
+
|
|
882
|
+
`profilesSampleRate` is **relative to `tracesSampleRate`** — a transaction must first be
|
|
883
|
+
sampled for tracing before profiling applies:
|
|
884
|
+
|
|
885
|
+
```typescript
|
|
886
|
+
Sentry.init({
|
|
887
|
+
dsn: "YOUR_DSN",
|
|
888
|
+
|
|
889
|
+
tracesSampleRate: 1.0, // 100% traced
|
|
890
|
+
profilesSampleRate: 1.0, // 100% of traced → 100% profiled (dev/testing only)
|
|
891
|
+
|
|
892
|
+
// Production example:
|
|
893
|
+
// tracesSampleRate: 0.2, // 20% traced
|
|
894
|
+
// profilesSampleRate: 0.5, // 50% of those → 10% of all transactions profiled
|
|
895
|
+
});
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
### Hermes + native platform profilers
|
|
899
|
+
|
|
900
|
+
By default both layers are profiled simultaneously:
|
|
901
|
+
|
|
902
|
+
1. **Hermes profiler** — JavaScript code executing in the Hermes engine
|
|
903
|
+
2. **Platform profilers** — native code (Swift/ObjC on iOS, Kotlin/Java on Android)
|
|
904
|
+
|
|
905
|
+
Control with `hermesProfilingIntegration`:
|
|
906
|
+
|
|
907
|
+
```typescript
|
|
908
|
+
Sentry.init({
|
|
909
|
+
dsn: "YOUR_DSN",
|
|
910
|
+
tracesSampleRate: 1.0,
|
|
911
|
+
profilesSampleRate: 1.0,
|
|
912
|
+
integrations: [
|
|
913
|
+
Sentry.hermesProfilingIntegration({
|
|
914
|
+
platformProfilers: true, // default: true — profile native code alongside JS
|
|
915
|
+
// Set false to profile ONLY JS (Hermes) without native code (SDK ≥ 5.33.0)
|
|
916
|
+
}),
|
|
917
|
+
],
|
|
918
|
+
});
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
### UI Profiling (experimental)
|
|
922
|
+
|
|
923
|
+
Continuous profiling tied to the app lifecycle rather than individual transactions.
|
|
924
|
+
Useful for catching performance issues that span multiple transactions.
|
|
925
|
+
|
|
926
|
+
```typescript
|
|
927
|
+
Sentry.init({
|
|
928
|
+
dsn: "YOUR_DSN",
|
|
929
|
+
tracesSampleRate: 1.0,
|
|
930
|
+
|
|
931
|
+
_experiments: {
|
|
932
|
+
profilingOptions: {
|
|
933
|
+
profileSessionSampleRate: 1.0, // fraction of app sessions to profile
|
|
934
|
+
lifecycle: "trace", // "trace" = profile only during active transactions
|
|
935
|
+
startOnAppStart: true, // begin profiling from the very first frame
|
|
936
|
+
},
|
|
937
|
+
},
|
|
938
|
+
});
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
> `androidProfilingOptions` is **deprecated** — use `profilingOptions` inside
|
|
942
|
+
> `_experiments` instead.
|
|
943
|
+
|
|
944
|
+
### Profiling version requirements
|
|
945
|
+
|
|
946
|
+
| Feature | Min SDK | Platforms |
|
|
947
|
+
| ---------------------------- | ---------------------------------- | ------------ |
|
|
948
|
+
| `profilesSampleRate` (basic) | `5.32.0` | iOS, Android |
|
|
949
|
+
| `platformProfilers: false` | `5.33.0` | iOS, Android |
|
|
950
|
+
| UI Profiling (experimental) | `7.9.0` (Android) · `7.12.0` (iOS) | iOS, Android |
|
|
951
|
+
|
|
952
|
+
---
|
|
953
|
+
|
|
954
|
+
## 14. Dynamic Sampling
|
|
955
|
+
|
|
956
|
+
`tracesSampler` gives you full control over sampling based on transaction properties at
|
|
957
|
+
the time the trace starts.
|
|
958
|
+
|
|
959
|
+
```typescript
|
|
960
|
+
Sentry.init({
|
|
961
|
+
dsn: "YOUR_DSN",
|
|
962
|
+
|
|
963
|
+
tracesSampler: ({ name, attributes, parentSampled }) => {
|
|
964
|
+
// Always sample critical user flows
|
|
965
|
+
if (name === "checkout" || name === "PaymentScreen") {
|
|
966
|
+
return 1.0;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// Never sample health checks
|
|
970
|
+
if (name.includes("HealthCheck")) {
|
|
971
|
+
return 0;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// Respect parent sampling decision for distributed traces
|
|
975
|
+
// (keeps frontend + backend in the same trace or both dropped)
|
|
976
|
+
if (parentSampled !== undefined) {
|
|
977
|
+
return parentSampled ? 1.0 : 0;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// Default: sample 10%
|
|
981
|
+
return 0.1;
|
|
982
|
+
},
|
|
983
|
+
});
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
### Head-based vs. tail-based sampling
|
|
987
|
+
|
|
988
|
+
| Approach | How | Tradeoff |
|
|
989
|
+
| ----------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------- |
|
|
990
|
+
| **Head-based** (`tracesSampleRate` / `tracesSampler`) | Decision made at trace start | Low overhead, but can’t sample based on outcome |
|
|
991
|
+
| **Tail-based** (Sentry Dynamic Sampling rules) | Decision made server-side after trace completes | Can prioritize errors/slow traces, requires Sentry Business plan |
|
|
992
|
+
|
|
993
|
+
For most React Native apps, head-based sampling with a `tracesSampler` is sufficient.
|
|
994
|
+
|
|
995
|
+
---
|
|
996
|
+
|
|
997
|
+
## 15. Configuration Reference
|
|
998
|
+
|
|
999
|
+
### `Sentry.init` options
|
|
1000
|
+
|
|
1001
|
+
| Option | Type | Default | Description |
|
|
1002
|
+
| ------------------------------ | ---------------------- | ------------------ | ------------------------------------------------------------- |
|
|
1003
|
+
| `tracesSampleRate` | `number` (0–1) | `undefined` | Uniform transaction sample rate |
|
|
1004
|
+
| `tracesSampler` | `function` | `undefined` | Dynamic sampler — overrides `tracesSampleRate` when set |
|
|
1005
|
+
| `profilesSampleRate` | `number` (0–1) | `undefined` | Profile sample rate, relative to traced transactions |
|
|
1006
|
+
| `tracePropagationTargets` | `(string \| RegExp)[]` | `[/.*/]` on mobile | URLs/patterns that receive `sentry-trace` + `baggage` headers |
|
|
1007
|
+
| `enableUserInteractionTracing` | `boolean` | `false` | Capture touch interaction transactions |
|
|
1008
|
+
| `enableAutoPerformanceTracing` | `boolean` | `true` | Master switch for all automatic instrumentation |
|
|
1009
|
+
| `parentSpanIsAlwaysRootSpan` | `boolean` | `true` | Flat span hierarchy — safe for async/await contexts |
|
|
1010
|
+
|
|
1011
|
+
### `reactNativeTracingIntegration` options
|
|
1012
|
+
|
|
1013
|
+
| Option | Type | Default | Description |
|
|
1014
|
+
| ---------------------------- | ---------------------- | --------- | -------------------------------------------------------- |
|
|
1015
|
+
| `beforeStartSpan` | `(context) => context` | — | Mutate span context before each navigation/pageload span |
|
|
1016
|
+
| `shouldCreateSpanForRequest` | `(url) => boolean` | — | Filter which outgoing requests get a span |
|
|
1017
|
+
| `idleTimeoutMs` | `number` | `1_000` | Ms of inactivity before ending the current transaction |
|
|
1018
|
+
| `finalTimeoutMs` | `number` | `600_000` | Hard maximum duration for any single transaction |
|
|
1019
|
+
|
|
1020
|
+
### `reactNavigationIntegration` options
|
|
1021
|
+
|
|
1022
|
+
| Option | Type | Default | Description |
|
|
1023
|
+
| --------------------------------------- | --------- | ------- | ------------------------------------------------------------ |
|
|
1024
|
+
| `enableTimeToInitialDisplay` | `boolean` | `false` | Auto-measure TTID per screen |
|
|
1025
|
+
| `routeChangeTimeoutMs` | `number` | `1_000` | Discard transaction if screen doesn’t mount within this time |
|
|
1026
|
+
| `ignoreEmptyBackNavigationTransactions` | `boolean` | `true` | Drop back-nav transactions with no child spans |
|
|
1027
|
+
| `useDispatchedActionData` | `boolean` | `false` | Include navigation action data in transaction metadata |
|
|
1028
|
+
|
|
1029
|
+
### `reactNativeNavigationIntegration` options (Wix RNN)
|
|
1030
|
+
|
|
1031
|
+
| Option | Type | Default | Description |
|
|
1032
|
+
| --------------------------------------- | ------------ | ------------ | ----------------------------------- |
|
|
1033
|
+
| `navigation` | `Navigation` | **required** | The RNN Navigation object |
|
|
1034
|
+
| `routeChangeTimeoutMs` | `number` | `1_000` | Discard stale transactions |
|
|
1035
|
+
| `enableTabsInstrumentation` | `boolean` | `false` | Create transactions on tab switches |
|
|
1036
|
+
| `ignoreEmptyBackNavigationTransactions` | `boolean` | `true` | Drop no-span back navigations |
|
|
1037
|
+
|
|
1038
|
+
### `hermesProfilingIntegration` options
|
|
1039
|
+
|
|
1040
|
+
| Option | Type | Default | Description |
|
|
1041
|
+
| ------------------- | --------- | ------- | ----------------------------------------------------------- |
|
|
1042
|
+
| `platformProfilers` | `boolean` | `true` | Profile native (Swift/ObjC/Kotlin/Java) alongside Hermes JS |
|
|
1043
|
+
|
|
1044
|
+
---
|
|
1045
|
+
|
|
1046
|
+
## 16. Mobile vs Web: Feature Matrix
|
|
1047
|
+
|
|
1048
|
+
| Capability | Web SDK | React Native SDK |
|
|
1049
|
+
| ------------------------------ | ---------------- | ------------------------------------------------------ |
|
|
1050
|
+
| App cold start tracking | ❌ | ✅ `measurements.app_start_cold` |
|
|
1051
|
+
| App warm start tracking | ❌ | ✅ `measurements.app_start_warm` |
|
|
1052
|
+
| Slow frames (Mobile Vital) | ❌ | ✅ Auto (requires `reactNativeTracingIntegration`) |
|
|
1053
|
+
| Frozen frames (Mobile Vital) | ❌ | ✅ Auto (requires `reactNativeTracingIntegration`) |
|
|
1054
|
+
| JS event loop stall tracking | ❌ | ✅ Auto (3 metrics: count, longest, total) |
|
|
1055
|
+
| Time to Initial Display (TTID) | ❌ | ✅ `enableTimeToInitialDisplay: true` |
|
|
1056
|
+
| Time to Full Display (TTFD) | ❌ | ✅ `<Sentry.TimeToFullDisplay record={...} />` |
|
|
1057
|
+
| Touch interaction tracing | ❌ | ✅ `enableUserInteractionTracing: true` |
|
|
1058
|
+
| Gesture tracing (RNGH v2) | ❌ | ✅ `sentryTraceGesture()` |
|
|
1059
|
+
| Hermes JS profiling | ❌ | ✅ `profilesSampleRate` + `hermesProfilingIntegration` |
|
|
1060
|
+
| Native platform profiling | ❌ | ✅ `platformProfilers: true` |
|
|
1061
|
+
| Navigation transactions | ✅ (SPA routers) | ✅ React Navigation · Expo Router · RNN |
|
|
1062
|
+
| Network span tracing | ✅ | ✅ fetch + XHR auto-instrumented |
|
|
1063
|
+
| Distributed tracing | ✅ | ✅ `tracePropagationTargets` |
|
|
1064
|
+
| Web Vitals (LCP, FID, CLS) | ✅ | ❌ (replaced by Mobile Vitals) |
|
|
1065
|
+
|
|
1066
|
+
---
|
|
1067
|
+
|
|
1068
|
+
## 17. Troubleshooting
|
|
1069
|
+
|
|
1070
|
+
| Issue | Cause | Solution |
|
|
1071
|
+
| -------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------ |
|
|
1072
|
+
| No transactions in Sentry | Tracing not enabled | Add `tracesSampleRate` > 0 and `reactNativeTracingIntegration()` to `integrations` |
|
|
1073
|
+
| App Start span missing | `Sentry.wrap(App)` not used | Wrap root component: `export default Sentry.wrap(App)` |
|
|
1074
|
+
| App Start time seems too long | Sentry follows platform vendor guidelines | Expected — Sentry measures the full user-perceptible start time, not internal JS init |
|
|
1075
|
+
| Navigation transactions not created | Integration not registered | Call `navigationIntegration.registerNavigationContainer(ref)` inside `onReady`, not before |
|
|
1076
|
+
| TTID/TTFD not appearing | Feature not enabled or wrong SDK version | Requires `enableTimeToInitialDisplay: true` and SDK ≥ 5.20.0, native build required |
|
|
1077
|
+
| TTID not firing on tab screens | Tab screens are preloaded | Add `<Sentry.TimeToInitialDisplay record={true} />` explicitly to each tab screen |
|
|
1078
|
+
| No interaction transactions | Missing `sentry-label` prop | Add `sentry-label="my_button"` to every interactive element you want to track |
|
|
1079
|
+
| `sentry-trace` header missing from requests | `tracePropagationTargets` doesn’t match URL | Check the full URL against your patterns — it matches against the entire URL string |
|
|
1080
|
+
| Backend receives header but trace not linked | Backend SDK not initialized | Ensure your backend uses a Sentry SDK with distributed tracing support |
|
|
1081
|
+
| Slow/frozen frames missing on Android | Missing `androidx.core` | Don’t exclude `androidx.core` from the Sentry Android dependency |
|
|
1082
|
+
| Profiling data not appearing | Profiling sample rate is 0 or traces not sampled | `profilesSampleRate` is relative to `tracesSampleRate` — both must be > 0 |
|
|
1083
|
+
| Component names minified in profiler | Production bundle minification | Configure Sentry Gradle/Xcode plugins and upload source maps |
|
|
1084
|
+
| Gesture spans not appearing | Wrong RNGH version | Only RNGH API v2 is supported — upgrade `react-native-gesture-handler` |
|
|
1085
|
+
| Stall metrics missing | `reactNativeTracingIntegration` not added | Stall tracking requires the integration — add it to `integrations: []` |
|
|
1086
|
+
| Transactions never finish | No idle timeout / long background spans | Adjust `idleTimeoutMs` in `reactNativeTracingIntegration` options |
|