sentry-react-native-sdk by getsentry/sentry-for-ai
npx skills add https://github.com/getsentry/sentry-for-ai --skill sentry-react-native-sdk一个具有明确导向的向导,它会扫描你的 React Native 或 Expo 项目,并指导你完成完整的 Sentry 设置——错误监控、追踪、性能分析、会话回放、日志记录等等。
@sentry/react-native、移动端错误追踪或用于 Expo 的 Sentry注意: 下面的 SDK 版本和 API 反映了撰写时的当前 Sentry 文档 (
@sentry/react-native≥6.0.0,最低推荐 ≥8.0.0)。在实施前,请务必对照 docs.sentry.io/platforms/react-native/ 进行验证。
在提出任何建议之前,运行以下命令来了解项目:
# 检测项目类型和现有的 Sentry
cat package.json | grep -E '"(react-native|expo|@expo|@sentry/react-native|sentry-expo)"'
# 区分 Expo 托管、Bare 和原生 RN
ls app.json app.config.js app.config.ts 2>/dev/null
cat app.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('Expo managed' if 'expo' in d else 'Bare/Vanilla')" 2>/dev/null
# 检查 Expo SDK 版本(重要:@sentry/react-native 要求 Expo SDK 50+)
cat package.json | grep '"expo"'
# 检测导航库
grep -E '"(@react-navigation/native|react-native-navigation)"' package.json
# 检测状态管理(Redux → 有面包屑集成可用)
grep -E '"(redux|@reduxjs/toolkit|zustand|mobx)"' package.json
# 检查现有的 Sentry 初始化
grep -r "Sentry.init" src/ app/ App.tsx App.js _layout.tsx 2>/dev/null | head -5
# 检测 Hermes(影响源映射处理)
cat android/app/build.gradle 2>/dev/null | grep -i hermes
cat ios/Podfile 2>/dev/null | grep -i hermes
# 检测 Expo Router
ls app/_layout.tsx app/_layout.js 2>/dev/null
# 检测后端以进行跨链
ls backend/ server/ api/ 2>/dev/null
find . -maxdepth 3 \( -name "go.mod" -o -name "requirements.txt" -o -name "Gemfile" -o -name "package.json" \) 2>/dev/null | grep -v node_modules | head -10
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
需要确定的内容:
| 问题 | 影响 |
|---|---|
package.json 中有 expo 吗? | Expo 路径(配置插件 + getSentryExpoConfig) vs Bare/原生 RN 路径 |
| Expo SDK ≥50? | 直接使用 @sentry/react-native;旧版 = sentry-expo(遗留,请勿使用) |
app.json 有 "expo" 键吗? | 托管 Expo — 向导最简单;配置插件处理所有原生配置 |
存在 app/_layout.tsx 吗? | Expo Router 项目 — 初始化放在 _layout.tsx |
package.json 中已有 @sentry/react-native 吗? | 跳过安装,跳转到功能配置 |
存在 @react-navigation/native 吗? | 推荐 reactNavigationIntegration 用于屏幕追踪 |
存在 react-native-navigation 吗? | 推荐 reactNativeNavigationIntegration (Wix) |
| 检测到后端目录吗? | 触发第四阶段跨链 |
根据你的发现提出具体建议。不要问开放式问题——直接提出方案:
推荐(核心覆盖范围 — 始终设置这些):
可选(增强可观测性):
Sentry.logger.* 进行结构化日志记录;链接到追踪以获取完整上下文推荐逻辑:
| 功能 | 何时推荐... |
|---|---|
| 错误监控 | 始终 — 任何移动应用的不可协商基线 |
| 追踪 | 移动端始终 — 应用启动、导航和网络延迟很重要 |
| 会话回放 | 面向用户的生产应用;可视化调试用户报告的问题 |
| 性能分析 | 性能敏感屏幕、启动时间问题或生产性能调查 |
| 日志记录 | 应用使用结构化日志记录,或者你希望在 Sentry 中进行日志到追踪的关联 |
| 用户反馈 | Beta 版或面向客户的应用,你希望收集用户提交的错误报告 |
建议:"对于你的 [Expo 托管 / Bare RN] 应用,我建议设置错误监控 + 追踪 + 会话回放。需要我同时添加性能分析和日志记录吗?"
| 项目类型 | 推荐设置 | 复杂度 |
|---|---|---|
| Expo 托管 (SDK 50+) | 向导 CLI 或手动使用配置插件 | 低 — 向导完成所有工作 |
| Expo Bare (SDK 50+) | 推荐向导 CLI | 中 — 处理 iOS/Android 配置 |
| 原生 React Native (0.69+) | 推荐向导 CLI | 中 — 处理 Xcode + Gradle |
| Expo SDK <50 | 使用 sentry-expo(遗留) | 参见遗留文档 |
你需要自己运行这个 — 向导会打开浏览器进行登录,并需要交互式输入,这是代理无法处理的。复制粘贴到你的终端:
npx @sentry/wizard@latest -i reactNative它处理登录、组织/项目选择、SDK 安装、原生配置、源映射上传和
Sentry.init()。以下是它创建/修改的内容:
文件 操作 目的 package.json安装 @sentry/react-native核心 SDK metro.config.js添加 @sentry/react-native/metro序列化器源映射生成 app.json添加 @sentry/react-native/expo插件(仅限 Expo)用于原生构建的配置插件 App.tsx/_layout.tsx添加 Sentry.init()和Sentry.wrap()SDK 初始化 ios/sentry.properties存储组织/项目/令牌 iOS 源映射 + dSYM 上传 android/sentry.properties存储组织/项目/令牌 Android 源映射上传 android/app/build.gradle添加 Sentry Gradle 插件 Android 源映射 + proguard ios/[AppName].xcodeproj包装 "Bundle RN" 构建阶段 + 添加 dSYM 上传 iOS 符号上传 .env.localSENTRY_AUTH_TOKEN认证令牌(添加到 .gitignore)完成后,返回并跳转到验证。
如果用户跳过了向导,请根据他们的项目类型继续下面的路径 B 或 C(手动设置)。
步骤 1 — 安装
npx expo install @sentry/react-native
步骤 2 — metro.config.js
const { getSentryExpoConfig } = require("@sentry/react-native/metro");
const config = getSentryExpoConfig(__dirname);
module.exports = config;
如果 metro.config.js 还不存在:
npx expo customize metro.config.js
# 然后将内容替换为上面的代码
步骤 3 — app.json — 添加 Expo 配置插件
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "YOUR_PROJECT_SLUG",
"organization": "YOUR_ORG_SLUG"
}
]
]
}
}
注意: 将
SENTRY_AUTH_TOKEN设置为环境变量用于原生构建 — 切勿将其提交到版本控制。
步骤 4 — 初始化 Sentry
对于 Expo Router (app/_layout.tsx):
import { Stack, useNavigationContainerRef } from "expo-router";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
import React from "react";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(), // 在 Expo Go 中禁用
});
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN ?? "YOUR_SENTRY_DSN",
sendDefaultPii: true,
// 追踪
tracesSampleRate: 1.0, // 生产环境降低到 0.1–0.2
// 性能分析
profilesSampleRate: 1.0,
// 会话回放
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
// 日志记录 (SDK ≥7.0.0)
enableLogs: true,
// 导航
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(), // 慢/冻结帧
environment: __DEV__ ? "development" : "production",
});
function RootLayout() {
const ref = useNavigationContainerRef();
React.useEffect(() => {
if (ref) {
navigationIntegration.registerNavigationContainer(ref);
}
}, [ref]);
return <Stack />;
}
export default Sentry.wrap(RootLayout);
对于 标准 Expo (App.tsx):
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(),
});
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN ?? "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(),
environment: __DEV__ ? "development" : "production",
});
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
{/* 你的导航内容在这里 */}
</NavigationContainer>
);
}
export default Sentry.wrap(App);
步骤 1 — 安装
npm install @sentry/react-native --save
cd ios && pod install
步骤 2 — metro.config.js
const { getDefaultConfig } = require("@react-native/metro-config");
const { withSentryConfig } = require("@sentry/react-native/metro");
const config = getDefaultConfig(__dirname);
module.exports = withSentryConfig(config);
步骤 3 — iOS:修改 Xcode 构建阶段
在 Xcode 中打开 ios/[AppName].xcodeproj。找到 "Bundle React Native code and images" 构建阶段,并将脚本内容替换为:
# RN 0.81.1+
set -e
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
SENTRY_XCODE="../node_modules/@sentry/react-native/scripts/sentry-xcode.sh"
/bin/sh -c "$WITH_ENVIRONMENT $SENTRY_XCODE"
步骤 4 — iOS:添加 "Upload Debug Symbols to Sentry" 构建阶段
在 Xcode 中添加一个新的 Run Script 构建阶段(在 bundle 阶段之后):
/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh
步骤 5 — iOS:ios/sentry.properties
defaults.url=https://sentry.io/
defaults.org=YOUR_ORG_SLUG
defaults.project=YOUR_PROJECT_SLUG
auth.token=YOUR_ORG_AUTH_TOKEN
步骤 6 — Android:android/app/build.gradle
在 android {} 块之前添加:
apply from: "../../node_modules/@sentry/react-native/sentry.gradle"
步骤 7 — Android:android/sentry.properties
defaults.url=https://sentry.io/
defaults.org=YOUR_ORG_SLUG
defaults.project=YOUR_PROJECT_SLUG
auth.token=YOUR_ORG_AUTH_TOKEN
步骤 8 — 初始化 Sentry (App.tsx 或入口点)
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
import * as Sentry from "@sentry/react-native";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: true,
});
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: true,
environment: __DEV__ ? "development" : "production",
});
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
{/* 你的导航内容在这里 */}
</NavigationContainer>
);
}
export default Sentry.wrap(App);
Sentry.init()这是推荐的起始配置,启用了所有功能:
import * as Sentry from "@sentry/react-native";
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
// 追踪 — 在高流量生产环境中降低到 0.1–0.2
tracesSampleRate: 1.0,
// 性能分析 — 在追踪事务的子集上运行
profilesSampleRate: 1.0,
// 会话回放 — 始终捕获错误会话,采样 10% 的所有会话
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
// 日志记录 — 启用 Sentry.logger.* API
enableLogs: true,
// 集成 — 移动端回放是选择加入的
integrations: [
Sentry.mobileReplayIntegration({
maskAllText: true, // 默认屏蔽文本以保护隐私
maskAllImages: true,
}),
],
// 原生帧追踪(在 Expo Go 中禁用)
enableNativeFramesTracking: true,
// 环境
environment: __DEV__ ? "development" : "production",
// 版本 — 从 CI 或构建系统设置
// release: "my-app@1.0.0+1",
// dist: "1",
});
// 必需:包装根组件以捕获 React 渲染错误
export default Sentry.wrap(App);
import { reactNavigationIntegration } from "@sentry/react-native";
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
const navigationIntegration = reactNavigationIntegration({
enableTimeToInitialDisplay: true, // 追踪每个屏幕的 TTID
routeChangeTimeoutMs: 1_000, // 路由更改的最大等待时间
ignoreEmptyBackNavigationTransactions: true,
});
// 添加到 Sentry.init 的 integrations 数组
Sentry.init({
integrations: [navigationIntegration],
// ...
});
// 在你的组件中:
const navigationRef = createNavigationContainerRef();
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
import * as Sentry from "@sentry/react-native";
import { Navigation } from "react-native-navigation";
Sentry.init({
integrations: [Sentry.reactNativeNavigationIntegration({ navigation: Navigation })],
// ...
});
始终包装你的根组件 — 这能启用 React 错误边界,并确保捕获组件树级别的崩溃:
export default Sentry.wrap(App);
逐个功能进行指导。为每个功能加载参考文件,按照其步骤操作,然后在继续之前进行验证:
| 功能 | 参考 | 何时加载 |
|---|---|---|
| 错误监控 | ${SKILL_ROOT}/references/error-monitoring.md | 始终(基线) |
| 追踪与性能 | ${SKILL_ROOT}/references/tracing.md | 移动端始终(应用启动、导航、网络) |
| 性能分析 | ${SKILL_ROOT}/references/profiling.md | 性能敏感的生产应用 |
| 会话回放 | ${SKILL_ROOT}/references/session-replay.md | 面向用户的应用 |
| 日志记录 | ${SKILL_ROOT}/references/logging.md | 结构化日志记录 / 日志到追踪关联 |
| 用户反馈 | ${SKILL_ROOT}/references/user-feedback.md | 收集用户提交的报告 |
对于每个功能:读取 ${SKILL_ROOT}/references/<功能>.md,严格按照步骤操作,验证其是否工作。
Sentry.init() 选项| 选项 | 类型 | 默认值 | 目的 |
|---|---|---|---|
dsn | string | — | 必需。 项目 DSN;如果为空则禁用 SDK。环境变量:SENTRY_DSN |
environment | string | — | 例如 "production"、"staging"。环境变量:SENTRY_ENVIRONMENT |
release | string | — | 应用版本,例如 "my-app@1.0.0+42"。环境变量:SENTRY_RELEASE |
dist | string | — | 构建号 / 变体标识符(最多 64 个字符) |
sendDefaultPii | boolean | false | 包含 PII:IP 地址、Cookie、用户数据 |
sampleRate | number | 1.0 | 错误事件采样率 (0.0–1.0) |
maxBreadcrumbs | number | 100 | 每个事件的最大面包屑数 |
attachStacktrace | boolean | true | 自动附加堆栈跟踪到消息 |
attachScreenshot | boolean | false | 错误时捕获屏幕截图 (SDK ≥4.11.0) |
attachViewHierarchy | boolean | false | 将 JSON 视图层次结构作为附件附加 |
debug | boolean | false | 详细的 SDK 输出。切勿在生产环境中使用 |
enabled | boolean | true | 完全禁用 SDK(例如用于测试) |
ignoreErrors | `string[] | RegExp[]` | — |
ignoreTransactions | `string[] | RegExp[]` | — |
maxCacheItems | number | 30 | 最大离线缓存信封数 |
defaultIntegrations | boolean | true | 设置为 false 以禁用所有默认集成 |
integrations | `array | function` | — |
| 选项 | 类型 | 默认值 | 目的 |
|---|---|---|---|
tracesSampleRate | number | 0 | 事务采样率 (0–1)。开发中使用 1.0 |
tracesSampler | function | — | 每个事务的采样;覆盖 tracesSampleRate |
tracePropagationTargets | `(string | RegExp)[]` | [/.*/] |
profilesSampleRate | number | 0 | 性能分析采样率(应用于追踪的事务) |
| 选项 | 类型 | 默认值 | 目的 |
|---|---|---|---|
enableNative | boolean | true | 设置为 false 仅用于 JS(无原生 SDK) |
enableNativeCrashHandling | boolean | true | 捕获原生硬崩溃(iOS/Android) |
enableNativeFramesTracking | boolean | — | 慢/冻结帧追踪。在 Expo Go 中禁用 |
enableWatchdogTerminationTracking | boolean | true | OOM 终止检测(iOS) |
enableAppHangTracking | boolean | true | 应用卡顿检测(iOS, tvOS, macOS) |
appHangTimeoutInterval | number | 2 | 归类为应用卡顿前的秒数(iOS) |
enableAutoPerformanceTracing | boolean | true | 自动性能检测 |
enableNdkScopeSync | boolean | true | Java→NDK 作用域同步(Android) |
attachThreads | boolean | false | 崩溃时自动附加所有线程(Android) |
autoInitializeNativeSdk | boolean | true | 设置为 false 用于手动原生初始化 |
onReady | function | — | 原生 SDK 初始化后的回调 |
| 选项 | 类型 | 默认值 | 目的 |
|---|---|---|---|
autoSessionTracking | boolean | true | 会话追踪(无崩溃用户/会话) |
sessionTrackingIntervalMillis | number | 30000 | 会话结束前的后台毫秒数 |
| 选项 | 类型 | 默认值 | 目的 |
|---|---|---|---|
replaysSessionSampleRate | number | 0 | 所有会话的录制比例 |
replaysOnErrorSampleRate | number | 0 | 错误会话的录制比例 |
| 选项 | 类型 | 目的 |
|---|---|---|
enableLogs | boolean | 启用 Sentry.logger.* API |
beforeSendLog | function | 在发送前过滤/修改日志 |
logsOrigin | `'native' | 'js' |
| 选项 | 类型 | 目的 |
|---|---|---|
beforeSend | `(event, hint) => event | null` |
beforeSendTransaction | `(event) => event | null` |
beforeBreadcrumb | `(breadcrumb, hint) => breadcrumb | null` |
onNativeLog | (log: { level, component, message }) => void | 拦截原生 SDK 日志消息并转发到 JS 控制台。仅在 debug: true 时触发 |
| 变量 | 目的 | 说明 |
|---|---|---|
SENTRY_DSN | 数据源名称 | 从 dsn 选项回退 |
SENTRY_AUTH_TOKEN | 上传源映射和 dSYM | 切勿提交 — 使用 CI 密钥 |
SENTRY_ORG | 组织 slug | 由向导和构建插件使用 |
SENTRY_PROJECT | 项目 slug | 由向导和构建插件使用 |
SENTRY_RELEASE | 发布标识符 | 从 release 选项回退 |
SENTRY_ENVIRONMENT | 环境名称 | 从 environment 选项回退 |
SENTRY_DISABLE_AUTO_UPLOAD | 跳过源映射上传 | 本地构建时设置为 true |
EXPO_PUBLIC_SENTRY_DSN | Expo 公共环境变量用于 DSN | 可安全嵌入客户端包 |
SENTRY_EAS_BUILD_CAPTURE_SUCCESS | EAS 构建钩子:捕获成功构建 | 在 EAS 密钥中设置为 true |
SENTRY_EAS_BUILD_TAGS | EAS 构建钩子:附加标签 JSON | 例如 {"team":"mobile"} |
源映射和调试符号是将压缩后的堆栈跟踪转换为可读内容的关键。正确设置后,Sentry 会显示引发错误的源代码的精确行号。
| 平台 | 上传内容 | 时机 |
|---|---|---|
| iOS (JS) | 源映射 (.map 文件) | Xcode 构建期间 |
| iOS (原生) | dSYM 包 | Xcode 归档 / Xcode Cloud 期间 |
| Android (JS) | 源映射 + Hermes .hbc.map | Gradle 构建期间 |
| Android (原生) | Proguard 映射 + NDK .so 文件 | Gradle 构建期间 |
@sentry/react-native/expo 配置插件会自动为原生构建设置上传钩子。源映射在 eas build 和 expo run:ios/android(发布版)期间上传。
SENTRY_AUTH_TOKEN=sntrys_... npx expo run:ios --configuration Release
如果需要手动上传源映射:
npx sentry-cli sourcemaps upload \
--org YOUR_ORG \
--project YOUR_PROJECT \
--release "my-app@1.0.0+1" \
./dist
这些集成会自动启用 — 无需配置:
| 集成 | 功能 |
|---|---|
ReactNativeErrorHandlers | 捕获未处理的 JS 异常和 Promise 拒绝 |
Release | 将所有事件附加发布/分发信息 |
Breadcrumbs | 将控制台日志、HTTP 请求、用户手势记录为面包屑 |
HttpClient | 添加 HTTP 请求/响应面包屑 |
DeviceContext | 将设备/OS/电池信息附加到事件 |
AppContext | 附加应用版本、包 ID 和内存信息 |
CultureContext | 附加区域设置和时区 |
Screenshot | 错误时捕获屏幕截图(当 attachScreenshot: true 时) |
ViewHierarchy | 附加视图层次结构(当 attachViewHierarchy: true 时) |
NativeLinkedErrors | 将 JS 错误链接到其对应的原生崩溃 |
| 集成 | 如何启用 |
|---|---|
mobileReplayIntegration() | 添加到 integrations 数组 |
reactNavigationIntegration() | 添加到 integrations 数组 |
reactNativeNavigationIntegration() | 添加到 integrations 数组(仅限 Wix) |
feedbackIntegration() | 添加到 integrations 数组(用户反馈组件) |
在 app.json 或 app.config.js 中配置插件:
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "my-project",
"organization": "my-org",
"note": "为原生构建设置 SENTRY_AUTH_TOKEN 环境变量"
}
]
]
}
}
或在 app.config.js 中(允许环境变量插值):
export default {
expo: {
plugins: [
[
"@sentry/react-native/expo",
{
url: "https://sentry.io/",
project: process.env.SENTRY_PROJECT,
organization: process.env.SENTRY_ORG,
},
],
],
},
};
在 Sentry 中监控你的 Expo Application Services (EAS) 构建。SDK 附带三个二进制钩子 — sentry-eas-build-on-complete、sentry-eas-build-on-error 和 sentry-eas-build-on-success — 它们将构建事件捕获为 Sentry 错误或消息。
步骤 1 — 在 package.json 中注册钩子
{
"scripts": {
"eas-build-on-complete": "sentry-eas-build-on-complete"
}
}
使用 eas-build-on-complete 在一个钩子中捕获失败和(可选)成功。或者,如果你想要独立控制,可以分别使用 eas-build-on-error 或 eas-build-on-success。
步骤 2 — 在你的 EAS 密钥中设置 SENTRY_DSN
eas secret:create --name SENTRY_DSN --value "https://...@sentry.io/..."
钩子从构建环境中读取 SENTRY_DSN — 它不与你的应用共享相同的 .env。
可选环境变量:
| 变量 | 目的 |
|---|---|
SENTRY_EAS_BUILD_CAPTURE_SUCCESS | 设置为 true 以同时捕获成功构建(默认:仅错误) |
SENTRY_EAS_BUILD_TAGS | 附加标签的 JSON 对象,例如 {"team":"mobile","channel":"production"} |
SENTRY_EAS_BUILD_ERROR_MESSAGE | 失败构建的自定义错误消息 |
SENTRY_EAS_BUILD_SUCCESS_MESSAGE | 成功构建的自定义消息 |
工作原理: 钩子脚本是一个 EAS npm 生命周期钩子。EAS 在构建过程结束时调用匹配
eas-build-on-*的package.json脚本。该脚本从@expo/env、.env或.env.sentry-build-plugin加载环境变量 — 不会覆盖环境中已有的 EAS 密钥。
在发布到生产环境之前,降低采样率并强化配置:
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN,
environment: __DEV__ ? "development" : "production",
// 在高流量生产环境中追踪 10–20% 的事务
tracesSampleRate: __DEV__ ? 1.0 : 0.1,
// 对 100% 的追踪事务进行性能分析(性能分析始终是追踪的子集)
profilesSampleRate: 1.0,
// 回放所有错误会话,采样 5% 的正常会话
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: __DEV__ ? 1.0 : 0.05,
// 设置 release 和 dist 以进行准确的源映射查找
release: "my-app@" + Application.nativeApplicationVersion,
dist: String(Application.nativeBuildVersion),
// 在生产环境中禁用调试日志记录
debug: __DEV__,
});
设置完成后,测试 Sentry 是否正在接收事件:
// 快速测试 — 抛出错误并由 Sentry.wrap(App) 捕获
<Button
title="测试 Sentry 错误"
onPress={() => {
throw new Error("我的第一个 Sentry 错误!");
}}
/>
// 或手动捕获
<Button
title="测试 Sentry 消息"
onPress={() => {
Sentry.captureMessage("Sentry 测试消息", "info");
}}
/>
检查 Sentry 仪表板:
enableLogs: true,则显示结构化日志条目⚠️ Expo Go 限制: 原生崩溃、会话回放、慢/冻结帧、TTID 和 TTFD 仅在原生构建(
eas build或expo run)中有效。Expo Go 在仅 JS 模式下运行。设置enableNativeFramesTracking: !isRunningInExpoGo()以避免警告。
如果没有出现任何内容:
debug: true — SDK 将日志记录到 Metro 控制台Sentry.wrap(App) 已应用于根组件完成 React Native 设置后,检查是否有缺少 Sentry 覆盖的后端或 Web 前端:
# 相邻的后端目录
ls ../backend ../server ../api 2>/dev/null
cat ../go.mod 2>/dev/null | head -3
cat ../requirements.txt ../pyproject.toml 2>/dev/null | head -3
cat ../Gemfile 2>/dev/null | head -3
ls ../backend/package.json ../server/package.json 2>/dev/null
# 同一或同级仓库中的 Web 前端
ls ../web ../frontend ../dashboard 2>/dev/null
cat ../web/package.json ../frontend/package.json 2>/dev/null | grep -E '"react"|"svelte"|"next"'
# 检查 OpenTelemetry(用于分布式追踪互操作)
grep -r "opentelemetry" ../backend/go.mod ../server/requirements.txt 2>/dev/null
如果存在没有 Sentry 的后端或 Web 前端,建议匹配的技能:
| 检测到 | 建议技能 |
|---|---|
Go 后端 (go.mod) | sentry-go-sdk |
Python 后端 (requirements.txt, pyproject.toml) | sentry-python-sdk |
Ruby 后端 (Gemfile) | sentry-ruby-sdk |
| Node.js 后端 (Express, Fastify 等) | @sentry/node — 参见 [docs.sentry.io/platforms/javascript/guides/express/](https://docs.sentry.io/platforms/javascript/guides |
All Skills > SDK Setup > React Native SDK
Opinionated wizard that scans your React Native or Expo project and guides you through complete Sentry setup — error monitoring, tracing, profiling, session replay, logging, and more.
@sentry/react-native, mobile error tracking, or Sentry for ExpoNote: SDK versions and APIs below reflect current Sentry docs at time of writing (
@sentry/react-native≥6.0.0, minimum recommended ≥8.0.0). Always verify against docs.sentry.io/platforms/react-native/ before implementing.
Run these commands to understand the project before making any recommendations:
# Detect project type and existing Sentry
cat package.json | grep -E '"(react-native|expo|@expo|@sentry/react-native|sentry-expo)"'
# Distinguish Expo managed vs bare vs vanilla RN
ls app.json app.config.js app.config.ts 2>/dev/null
cat app.json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('Expo managed' if 'expo' in d else 'Bare/Vanilla')" 2>/dev/null
# Check Expo SDK version (important: Expo SDK 50+ required for @sentry/react-native)
cat package.json | grep '"expo"'
# Detect navigation library
grep -E '"(@react-navigation/native|react-native-navigation)"' package.json
# Detect state management (Redux → breadcrumb integration available)
grep -E '"(redux|@reduxjs/toolkit|zustand|mobx)"' package.json
# Check for existing Sentry initialization
grep -r "Sentry.init" src/ app/ App.tsx App.js _layout.tsx 2>/dev/null | head -5
# Detect Hermes (affects source map handling)
cat android/app/build.gradle 2>/dev/null | grep -i hermes
cat ios/Podfile 2>/dev/null | grep -i hermes
# Detect Expo Router
ls app/_layout.tsx app/_layout.js 2>/dev/null
# Detect backend for cross-link
ls backend/ server/ api/ 2>/dev/null
find . -maxdepth 3 \( -name "go.mod" -o -name "requirements.txt" -o -name "Gemfile" -o -name "package.json" \) 2>/dev/null | grep -v node_modules | head -10
What to determine:
| Question | Impact |
|---|---|
expo in package.json? | Expo path (config plugin + getSentryExpoConfig) vs bare/vanilla RN path |
| Expo SDK ≥50? | @sentry/react-native directly; older = sentry-expo (legacy, do not use) |
app.json has "expo" key? | Managed Expo — wizard is simplest; config plugin handles all native config |
app/_layout.tsx present? |
Present a concrete recommendation based on what you found. Don't ask open-ended questions — lead with a proposal:
Recommended (core coverage — always set up these):
Optional (enhanced observability):
Sentry.logger.*; links to traces for full contextRecommendation logic:
| Feature | Recommend when... |
|---|---|
| Error Monitoring | Always — non-negotiable baseline for any mobile app |
| Tracing | Always for mobile — app start, navigation, and network latency matter |
| Session Replay | User-facing production app; debug user-reported issues visually |
| Profiling | Performance-sensitive screens, startup time concerns, or production perf investigations |
| Logging | App uses structured logging, or you want log-to-trace correlation in Sentry |
| User Feedback | Beta or customer-facing app where you want user-submitted bug reports |
Propose: "For your [Expo managed / bare RN] app, I recommend setting up Error Monitoring + Tracing + Session Replay. Want me to also add Profiling and Logging?"
| Project type | Recommended setup | Complexity |
|---|---|---|
| Expo managed (SDK 50+) | Wizard CLI or manual with config plugin | Low — wizard does everything |
| Expo bare (SDK 50+) | Wizard CLI recommended | Medium — handles iOS/Android config |
| Vanilla React Native (0.69+) | Wizard CLI recommended | Medium — handles Xcode + Gradle |
| Expo SDK <50 | Use sentry-expo (legacy) | See legacy docs |
You need to run this yourself — the wizard opens a browser for login and requires interactive input that the agent can't handle. Copy-paste into your terminal:
npx @sentry/wizard@latest -i reactNativeIt handles login, org/project selection, SDK installation, native config, source map upload, and
Sentry.init(). Here's what it creates/modifies:
File Action Purpose package.jsonInstalls @sentry/react-nativeCore SDK metro.config.jsAdds @sentry/react-native/metroserializer
If the user skips the wizard, proceed with Path B or C (Manual Setup) below based on their project type.
Step 1 — Install
npx expo install @sentry/react-native
Step 2 —metro.config.js
const { getSentryExpoConfig } = require("@sentry/react-native/metro");
const config = getSentryExpoConfig(__dirname);
module.exports = config;
If metro.config.js doesn't exist yet:
npx expo customize metro.config.js
# Then replace contents with the above
Step 3 —app.json — Add Expo config plugin
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "YOUR_PROJECT_SLUG",
"organization": "YOUR_ORG_SLUG"
}
]
]
}
}
Note: Set
SENTRY_AUTH_TOKENas an environment variable for native builds — never commit it to version control.
Step 4 — Initialize Sentry
For Expo Router (app/_layout.tsx):
import { Stack, useNavigationContainerRef } from "expo-router";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
import React from "react";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(), // disabled in Expo Go
});
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN ?? "YOUR_SENTRY_DSN",
sendDefaultPii: true,
// Tracing
tracesSampleRate: 1.0, // lower to 0.1–0.2 in production
// Profiling
profilesSampleRate: 1.0,
// Session Replay
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
// Logging (SDK ≥7.0.0)
enableLogs: true,
// Navigation
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(), // slow/frozen frames
environment: __DEV__ ? "development" : "production",
});
function RootLayout() {
const ref = useNavigationContainerRef();
React.useEffect(() => {
if (ref) {
navigationIntegration.registerNavigationContainer(ref);
}
}, [ref]);
return <Stack />;
}
export default Sentry.wrap(RootLayout);
For standard Expo (App.tsx):
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
import { isRunningInExpoGo } from "expo";
import * as Sentry from "@sentry/react-native";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: !isRunningInExpoGo(),
});
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN ?? "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: !isRunningInExpoGo(),
environment: __DEV__ ? "development" : "production",
});
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
{/* your navigation here */}
</NavigationContainer>
);
}
export default Sentry.wrap(App);
Step 1 — Install
npm install @sentry/react-native --save
cd ios && pod install
Step 2 —metro.config.js
const { getDefaultConfig } = require("@react-native/metro-config");
const { withSentryConfig } = require("@sentry/react-native/metro");
const config = getDefaultConfig(__dirname);
module.exports = withSentryConfig(config);
Step 3 — iOS: Modify Xcode build phase
Open ios/[AppName].xcodeproj in Xcode. Find the "Bundle React Native code and images" build phase and replace the script content with:
# RN 0.81.1+
set -e
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
SENTRY_XCODE="../node_modules/@sentry/react-native/scripts/sentry-xcode.sh"
/bin/sh -c "$WITH_ENVIRONMENT $SENTRY_XCODE"
Step 4 — iOS: Add "Upload Debug Symbols to Sentry" build phase
Add a new Run Script build phase in Xcode (after the bundle phase):
/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh
Step 5 — iOS:ios/sentry.properties
defaults.url=https://sentry.io/
defaults.org=YOUR_ORG_SLUG
defaults.project=YOUR_PROJECT_SLUG
auth.token=YOUR_ORG_AUTH_TOKEN
Step 6 — Android:android/app/build.gradle
Add before the android {} block:
apply from: "../../node_modules/@sentry/react-native/sentry.gradle"
Step 7 — Android:android/sentry.properties
defaults.url=https://sentry.io/
defaults.org=YOUR_ORG_SLUG
defaults.project=YOUR_PROJECT_SLUG
auth.token=YOUR_ORG_AUTH_TOKEN
Step 8 — Initialize Sentry (App.tsx or entry point)
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
import * as Sentry from "@sentry/react-native";
const navigationIntegration = Sentry.reactNavigationIntegration({
enableTimeToInitialDisplay: true,
});
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
tracesSampleRate: 1.0,
profilesSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
enableLogs: true,
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],
enableNativeFramesTracking: true,
environment: __DEV__ ? "development" : "production",
});
const navigationRef = createNavigationContainerRef();
function App() {
return (
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
{/* your navigation here */}
</NavigationContainer>
);
}
export default Sentry.wrap(App);
Sentry.init()This is the recommended starting configuration with all features enabled:
import * as Sentry from "@sentry/react-native";
Sentry.init({
dsn: "YOUR_SENTRY_DSN",
sendDefaultPii: true,
// Tracing — lower to 0.1–0.2 in high-traffic production
tracesSampleRate: 1.0,
// Profiling — runs on a subset of traced transactions
profilesSampleRate: 1.0,
// Session Replay — always capture on error, sample 10% of all sessions
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
// Logging — enable Sentry.logger.* API
enableLogs: true,
// Integrations — mobile replay is opt-in
integrations: [
Sentry.mobileReplayIntegration({
maskAllText: true, // masks text by default for privacy
maskAllImages: true,
}),
],
// Native frames tracking (disable in Expo Go)
enableNativeFramesTracking: true,
// Environment
environment: __DEV__ ? "development" : "production",
// Release — set from CI or build system
// release: "my-app@1.0.0+1",
// dist: "1",
});
// REQUIRED: Wrap root component to capture React render errors
export default Sentry.wrap(App);
import { reactNavigationIntegration } from "@sentry/react-native";
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
const navigationIntegration = reactNavigationIntegration({
enableTimeToInitialDisplay: true, // track TTID per screen
routeChangeTimeoutMs: 1_000, // max wait for route change to settle
ignoreEmptyBackNavigationTransactions: true,
});
// Add to Sentry.init integrations array
Sentry.init({
integrations: [navigationIntegration],
// ...
});
// In your component:
const navigationRef = createNavigationContainerRef();
<NavigationContainer
ref={navigationRef}
onReady={() => {
navigationIntegration.registerNavigationContainer(navigationRef);
}}
>
import * as Sentry from "@sentry/react-native";
import { Navigation } from "react-native-navigation";
Sentry.init({
integrations: [Sentry.reactNativeNavigationIntegration({ navigation: Navigation })],
// ...
});
Always wrap your root component — this enables React error boundaries and ensures crashes at the component tree level are captured:
export default Sentry.wrap(App);
Walk through features one at a time. Load the reference file for each, follow its steps, then verify before moving on:
| Feature | Reference | Load when... |
|---|---|---|
| Error Monitoring | ${SKILL_ROOT}/references/error-monitoring.md | Always (baseline) |
| Tracing & Performance | ${SKILL_ROOT}/references/tracing.md | Always for mobile (app start, navigation, network) |
| Profiling | ${SKILL_ROOT}/references/profiling.md | Performance-sensitive production apps |
| Session Replay | ${SKILL_ROOT}/references/session-replay.md | User-facing apps |
| Logging |
For each feature: Read ${SKILL_ROOT}/references/<feature>.md, follow steps exactly, verify it works.
Sentry.init() Options| Option | Type | Default | Purpose |
|---|---|---|---|
dsn | string | — | Required. Project DSN; SDK disabled if empty. Env: SENTRY_DSN |
environment | string | — | e.g., "production", "staging". Env: |
| Option | Type | Default | Purpose |
|---|---|---|---|
tracesSampleRate | number | 0 | Transaction sample rate (0–1). Use 1.0 in dev |
tracesSampler | function | — | Per-transaction sampling; overrides tracesSampleRate |
| Option | Type | Default | Purpose |
|---|---|---|---|
enableNative | boolean | true | Set false for JS-only (no native SDK) |
enableNativeCrashHandling | boolean | true | Capture native hard crashes (iOS/Android) |
| Option | Type | Default | Purpose |
|---|---|---|---|
autoSessionTracking | boolean | true | Session tracking (crash-free users/sessions) |
sessionTrackingIntervalMillis | number | 30000 | ms of background before session ends |
| Option | Type | Default | Purpose |
|---|---|---|---|
replaysSessionSampleRate | number | 0 | Fraction of all sessions recorded |
replaysOnErrorSampleRate | number | 0 | Fraction of error sessions recorded |
| Option | Type | Purpose |
|---|---|---|
enableLogs | boolean | Enable Sentry.logger.* API |
beforeSendLog | function | Filter/modify logs before sending |
logsOrigin | `'native' | 'js' |
| Option | Type | Purpose |
|---|---|---|
beforeSend | `(event, hint) => event | null` |
beforeSendTransaction | `(event) => event | null` |
beforeBreadcrumb | `(breadcrumb, hint) => breadcrumb | null` |
onNativeLog | (log: { level, component, message }) => void | Intercept native SDK log messages and forward to JS console. Only fires when debug: true |
| Variable | Purpose | Notes |
|---|---|---|
SENTRY_DSN | Data Source Name | Falls back from dsn option |
SENTRY_AUTH_TOKEN | Upload source maps and dSYMs | Never commit — use CI secrets |
SENTRY_ORG | Organization slug | Used by wizard and build plugins |
SENTRY_PROJECT | Project slug | Used by wizard and build plugins |
Source maps and debug symbols are what transform minified stack traces into readable ones. When set up correctly, Sentry shows you the exact line of your source code that threw.
| Platform | What's uploaded | When |
|---|---|---|
| iOS (JS) | Source maps (.map files) | During Xcode build |
| iOS (Native) | dSYM bundles | During Xcode archive / Xcode Cloud |
| Android (JS) | Source maps + Hermes .hbc.map | During Gradle build |
| Android (Native) | Proguard mapping + NDK .so files | During Gradle build |
The @sentry/react-native/expo config plugin automatically sets up upload hooks for native builds. Source maps are uploaded during eas build and expo run:ios/android (release).
SENTRY_AUTH_TOKEN=sntrys_... npx expo run:ios --configuration Release
If you need to manually upload source maps:
npx sentry-cli sourcemaps upload \
--org YOUR_ORG \
--project YOUR_PROJECT \
--release "my-app@1.0.0+1" \
./dist
These integrations are enabled automatically — no config needed:
| Integration | What it does |
|---|---|
ReactNativeErrorHandlers | Catches unhandled JS exceptions and promise rejections |
Release | Attaches release/dist to all events |
Breadcrumbs | Records console logs, HTTP requests, user gestures as breadcrumbs |
HttpClient | Adds HTTP request/response breadcrumbs |
DeviceContext | Attaches device/OS/battery info to events |
AppContext |
| Integration | How to enable |
|---|---|
mobileReplayIntegration() | Add to integrations array |
reactNavigationIntegration() | Add to integrations array |
reactNativeNavigationIntegration() | Add to integrations array (Wix only) |
feedbackIntegration() | Add to array (user feedback widget) |
Configure the plugin in app.json or app.config.js:
{
"expo": {
"plugins": [
[
"@sentry/react-native/expo",
{
"url": "https://sentry.io/",
"project": "my-project",
"organization": "my-org",
"note": "Set SENTRY_AUTH_TOKEN env var for native builds"
}
]
]
}
}
Or in app.config.js (allows env var interpolation):
export default {
expo: {
plugins: [
[
"@sentry/react-native/expo",
{
url: "https://sentry.io/",
project: process.env.SENTRY_PROJECT,
organization: process.env.SENTRY_ORG,
},
],
],
},
};
Monitor your Expo Application Services (EAS) builds in Sentry. The SDK ships three binary hooks — sentry-eas-build-on-complete, sentry-eas-build-on-error, and sentry-eas-build-on-success — that capture build events as Sentry errors or messages.
Step 1 — Register the hook inpackage.json
{
"scripts": {
"eas-build-on-complete": "sentry-eas-build-on-complete"
}
}
Use eas-build-on-complete to capture both failures and (optionally) successes in one hook. Alternatively use eas-build-on-error or eas-build-on-success separately if you want independent control.
Step 2 — SetSENTRY_DSN in your EAS secrets
eas secret:create --name SENTRY_DSN --value "https://...@sentry.io/..."
The hook reads SENTRY_DSN from the build environment — it does not share the same .env as your app.
Optional environment variables:
| Variable | Purpose |
|---|---|
SENTRY_EAS_BUILD_CAPTURE_SUCCESS | Set true to also capture successful builds (default: errors only) |
SENTRY_EAS_BUILD_TAGS | JSON object of additional tags, e.g., {"team":"mobile","channel":"production"} |
SENTRY_EAS_BUILD_ERROR_MESSAGE | Custom error message for failed builds |
SENTRY_EAS_BUILD_SUCCESS_MESSAGE | Custom message for successful builds |
How it works: The hook script is an EAS npm lifecycle hook. EAS calls
package.jsonscripts matchingeas-build-on-*at the end of the build process. The script loads env from@expo/env,.env, or.env.sentry-build-plugin— without overwriting EAS secrets already in the environment.
Lower sample rates and harden config before shipping to production:
Sentry.init({
dsn: process.env.EXPO_PUBLIC_SENTRY_DSN,
environment: __DEV__ ? "development" : "production",
// Trace 10–20% of transactions in high-traffic production
tracesSampleRate: __DEV__ ? 1.0 : 0.1,
// Profile 100% of traced transactions (profiling is always a subset of tracing)
profilesSampleRate: 1.0,
// Replay all error sessions, sample 5% of normal sessions
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: __DEV__ ? 1.0 : 0.05,
// Set release and dist for accurate source map lookup
release: "my-app@" + Application.nativeApplicationVersion,
dist: String(Application.nativeBuildVersion),
// Disable debug logging in production
debug: __DEV__,
});
After setup, test that Sentry is receiving events:
// Quick test — throws and Sentry.wrap(App) catches it
<Button
title="Test Sentry Error"
onPress={() => {
throw new Error("My first Sentry error!");
}}
/>
// Or capture manually
<Button
title="Test Sentry Message"
onPress={() => {
Sentry.captureMessage("Sentry test message", "info");
}}
/>
Check the Sentry dashboard:
enableLogs: true⚠️ Expo Go limitation: Native crashes, session replay, slow/frozen frames, TTID, and TTFD only work in native builds (
eas buildorexpo run). Expo Go runs in a JS-only mode. SetenableNativeFramesTracking: !isRunningInExpoGo()to avoid warnings.
If nothing appears:
debug: true — SDK logs to Metro consoleSentry.wrap(App) is applied to the root componentAfter completing React Native setup, check for a backend or web frontend missing Sentry coverage:
# Adjacent backend directories
ls ../backend ../server ../api 2>/dev/null
cat ../go.mod 2>/dev/null | head -3
cat ../requirements.txt ../pyproject.toml 2>/dev/null | head -3
cat ../Gemfile 2>/dev/null | head -3
ls ../backend/package.json ../server/package.json 2>/dev/null
# Web frontend in same or sibling repo
ls ../web ../frontend ../dashboard 2>/dev/null
cat ../web/package.json ../frontend/package.json 2>/dev/null | grep -E '"react"|"svelte"|"next"'
# Check for OpenTelemetry (for distributed tracing interop)
grep -r "opentelemetry" ../backend/go.mod ../server/requirements.txt 2>/dev/null
If a backend or web frontend exists without Sentry, suggest the matching skill:
| Detected | Suggest skill |
|---|---|
Go backend (go.mod) | sentry-go-sdk |
Python backend (requirements.txt, pyproject.toml) | sentry-python-sdk |
Ruby backend (Gemfile) | sentry-ruby-sdk |
| Node.js backend (Express, Fastify, etc.) | @sentry/node — see |
Distributed tracing setup — if the backend skill is added, configure tracePropagationTargets in React Native to propagate trace context to your API:
Sentry.init({
tracePropagationTargets: [
"localhost",
/^https:\/\/api\.yourapp\.com/,
],
// ...
});
This links mobile transactions to backend traces in the Sentry waterfall view.
| Issue | Solution |
|---|---|
| Events not appearing in Sentry | Set debug: true, check Metro/Xcode console for SDK errors; verify DSN is correct |
pod install fails | Run cd ios && pod install --repo-update; check CocoaPods version |
| iOS build fails with Sentry script | Verify the "Bundle React Native code and images" script was replaced (not appended to) |
Android build fails after adding sentry.gradle | Ensure apply from line is before the android {} block in build.gradle |
Weekly Installs
238
Repository
GitHub Stars
82
First Seen
Feb 28, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli237
codex237
cursor237
amp236
kimi-cli236
opencode236
Electron应用自动化指南:使用agent-browser通过CDP实现桌面应用自动化
11,900 周安装
Expo Router project — init goes in _layout.tsx |
@sentry/react-native already in package.json? | Skip install, jump to feature config |
@react-navigation/native present? | Recommend reactNavigationIntegration for screen tracking |
react-native-navigation present? | Recommend reactNativeNavigationIntegration (Wix) |
| Backend directory detected? | Trigger Phase 4 cross-link |
| Source map generation |
app.json | Adds @sentry/react-native/expo plugin (Expo only) | Config plugin for native builds |
App.tsx / _layout.tsx | Adds Sentry.init() and Sentry.wrap() | SDK initialization |
ios/sentry.properties | Stores org/project/token | iOS source map + dSYM upload |
android/sentry.properties | Stores org/project/token | Android source map upload |
android/app/build.gradle | Adds Sentry Gradle plugin | Android source maps + proguard |
ios/[AppName].xcodeproj | Wraps "Bundle RN" build phase + adds dSYM upload | iOS symbol upload |
.env.local | SENTRY_AUTH_TOKEN | Auth token (add to .gitignore) |
Once it finishes, come back and skip toVerification.
${SKILL_ROOT}/references/logging.md| Structured logging / log-to-trace correlation |
| User Feedback | ${SKILL_ROOT}/references/user-feedback.md | Collecting user-submitted reports |
SENTRY_ENVIRONMENTrelease | string | — | App version, e.g., "my-app@1.0.0+42". Env: SENTRY_RELEASE |
dist | string | — | Build number / variant identifier (max 64 chars) |
sendDefaultPii | boolean | false | Include PII: IP address, cookies, user data |
sampleRate | number | 1.0 | Error event sampling (0.0–1.0) |
maxBreadcrumbs | number | 100 | Max breadcrumbs per event |
attachStacktrace | boolean | true | Auto-attach stack traces to messages |
attachScreenshot | boolean | false | Capture screenshot on error (SDK ≥4.11.0) |
attachViewHierarchy | boolean | false | Attach JSON view hierarchy as attachment |
debug | boolean | false | Verbose SDK output. Never use in production |
enabled | boolean | true | Disable SDK entirely (e.g., for testing) |
ignoreErrors | `string[] | RegExp[]` | — |
ignoreTransactions | `string[] | RegExp[]` | — |
maxCacheItems | number | 30 | Max offline-cached envelopes |
defaultIntegrations | boolean | true | Set false to disable all default integrations |
integrations | `array | function` | — |
tracePropagationTargets | `(string | RegExp)[]` | [/.*/] |
profilesSampleRate | number | 0 | Profiling sample rate (applied to traced transactions) |
enableNativeFramesTracking | boolean | — | Slow/frozen frames tracking. Disable in Expo Go |
enableWatchdogTerminationTracking | boolean | true | OOM kill detection (iOS) |
enableAppHangTracking | boolean | true | App hang detection (iOS, tvOS, macOS) |
appHangTimeoutInterval | number | 2 | Seconds before classifying as app hang (iOS) |
enableAutoPerformanceTracing | boolean | true | Auto performance instrumentation |
enableNdkScopeSync | boolean | true | Java→NDK scope sync (Android) |
attachThreads | boolean | false | Auto-attach all threads on crash (Android) |
autoInitializeNativeSdk | boolean | true | Set false for manual native init |
onReady | function | — | Callback after native SDKs initialize |
SENTRY_RELEASE| Release identifier |
Falls back from release option |
SENTRY_ENVIRONMENT | Environment name | Falls back from environment option |
SENTRY_DISABLE_AUTO_UPLOAD | Skip source map upload | Set true during local builds |
EXPO_PUBLIC_SENTRY_DSN | Expo public env var for DSN | Safe to embed in client bundle |
SENTRY_EAS_BUILD_CAPTURE_SUCCESS | EAS build hook: capture successful builds | Set true in EAS secrets |
SENTRY_EAS_BUILD_TAGS | EAS build hook: additional tags JSON | e.g., {"team":"mobile"} |
| Attaches app version, bundle ID, and memory info |
CultureContext | Attaches locale and timezone |
Screenshot | Captures screenshot on error (when attachScreenshot: true) |
ViewHierarchy | Attaches view hierarchy (when attachViewHierarchy: true) |
NativeLinkedErrors | Links JS errors to their native crash counterparts |
integrations| React / Next.js web | sentry-react-sdk |
| Svelte / SvelteKit web | sentry-svelte-sdk |
| Android Gradle 8+ compatibility issue | Use sentry-android-gradle-plugin ≥4.0.0; check sentry.gradle version in your SDK |
| Source maps not uploading | Verify sentry.properties has a valid auth.token; check build logs for sentry-cli output |
| Source maps not resolving in Sentry | Confirm release and dist in Sentry.init() match the uploaded bundle metadata |
| Hermes source maps not working | Hermes emits .hbc.map — the Gradle plugin handles this automatically; verify sentry.gradle is applied |
| Session replay not recording | Must use a native build (not Expo Go); confirm mobileReplayIntegration() is in integrations |
| Replay shows blank/black screens | Check that maskAllText/maskAllImages settings match your privacy requirements |
| Slow/frozen frames not tracked | Set enableNativeFramesTracking: true and confirm you're on a native build (not Expo Go) |
| TTID / TTFD not appearing | Requires enableTimeToInitialDisplay: true in reactNavigationIntegration() on a native build |
| App crashes on startup after adding Sentry | Likely a native initialization error — check Xcode/Logcat logs; try enableNative: false to isolate |
| Expo SDK 49 or older | Use sentry-expo (legacy package); @sentry/react-native requires Expo SDK 50+ |
isRunningInExpoGo import error | Import from expo package: import { isRunningInExpoGo } from "expo" |
| Node not found during Xcode build | Add export NODE_BINARY=$(which node) to the Xcode build phase, or symlink: ln -s $(which node) /usr/local/bin/node |
| Expo Go warning about native features | Use isRunningInExpoGo() guard: enableNativeFramesTracking: !isRunningInExpoGo() |
beforeSend not firing for native crashes | Expected — beforeSend only intercepts JS-layer errors; native crashes bypass it |
| Android 15+ (16KB page size) crash | Upgrade to @sentry/react-native ≥6.3.0 |
| Too many transactions in dashboard | Lower tracesSampleRate to 0.1 or use tracesSampler to drop health checks |
SENTRY_AUTH_TOKEN exposed in app bundle | SENTRY_AUTH_TOKEN is for build-time upload only — never pass it to Sentry.init() |
| EAS Build: Sentry auth token missing | Set SENTRY_AUTH_TOKEN as an EAS secret: eas secret:create --name SENTRY_AUTH_TOKEN |