sentry-react-native-sdk について
React Native と Expo のプロジェクトで Sentry を設定するためのスキルです。構成を判別し、エラー監視や追加のオブザーバビリティ機能に応じた手順を案内します。
主な機能
- 01React Native と Expo の構成判定
- 02Sentry の導入と初期化の案内
- 03エラー監視、トレース、リプレイへの対応
- 04プロファイリング、ログ、フィードバックの追加設定
- 05検証手順と設定リファレンス
活用シーン
- 01新しい React Native アプリへの Sentry 導入
- 02Expo プロジェクトの監視設定
- 03既存設定へのパフォーマンス機能の追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ getsentry/ sentry-agent-skills --skill sentry-react-native-sdkインストール後、Claude Code で/sentry-react-native-sdkを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/error-monitoring.mdlogging.mdprofiling.mdsession-replay.mdtracing.mduser-feedback.md詳細
Sentry React Native SDK
React Native または Expo プロジェクトをスキャンし、Sentry の完全なセットアップ(エラーモニタリング、トレーシング、プロファイリング、セッションリプレイ、ロギングなど)を案内する、方針に基づいたウィザードです。
このスキルを呼び出すタイミング
- ユーザーが、RN または Expo アプリに「Sentry を追加して」または「Sentry をセットアップして」と依頼した場合
- ユーザーが React Native でのエラーモニタリング、トレーシング、プロファイリング、セッションリプレイ、ロギングを希望している場合
- ユーザーが
@sentry/react-native、モバイルのエラートラッキング、または Expo 向け Sentry について言及した場合 - ユーザーが iOS/Android でネイティブクラッシュ、ANR、またはアプリのハングを監視したい場合
注: 以下の SDK バージョンと API は、執筆時点での Sentry ドキュメント(
@sentry/react-native≥6.0.0、推奨される最小バージョン ≥8.0.0)に基づいています。 実装前に、必ずdocs.sentry.io/platforms/react-native/で確認してください。
フェーズ 1:検出
推奨事項を提示する前に、以下のコマンドを実行してプロジェクトの状況を把握します。
# 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
確認する項目:
| 質問 | 影響 |
|---|---|
package.json に expo があるか? | Expo の手順(設定プラグイン + getSentryExpoConfig)か、Bare/Vanilla RN の手順かを判断します |
| Expo SDK ≥50 か? | @sentry/react-native を直接使用します。古い場合は sentry-expo(レガシー、使用しない)です |
app.json に "expo" キーがあるか? | Managed Expo です。ウィザードが最も簡単で、設定プラグインがすべてのネイティブ設定を処理します |
app/_layout.tsx があるか? | Expo Router プロジェクトです。初期化処理は _layout.tsx に配置します |
package.json に @sentry/react-native がすでにあるか? | インストールを省略し、機能の設定に進みます |
@react-navigation/native があるか? | 画面トラッキング用に reactNavigationIntegration を推奨します |
react-native-navigation があるか? | reactNativeNavigationIntegration(Wix)を推奨します |
| バックエンドのディレクトリが検出されたか? | フェーズ 4 への関連付けを行います |
フェーズ 2:推奨
確認結果に基づいて、具体的な推奨事項を提示します。自由回答式の質問はせず、提案から始めます。
推奨(基本的なカバー範囲 — 常にセットアップする項目):
- ✅ エラーモニタリング — JS 例外、ネイティブクラッシュ(iOS + Android)、ANR、アプリのハングをキャプチャします
- ✅ トレーシング — モバイルのパフォーマンスは非常に重要です。ナビゲーション、アプリ起動、ネットワークリクエストを自動計測します
- ✅ セッションリプレイ — モバイルのリプレイではスクリーンショットとタッチイベントをキャプチャし、ユーザーの問題のデバッグに役立てます
任意(可観測性の強化):
- ⚡ プロファイリング — iOS で CPU プロファイリングを行います(JS プロファイリングはクロスプラットフォーム対応)。本番環境でのオーバーヘッドは小さくなります
- ⚡ ロギング —
Sentry.logger.*による構造化ログを記録し、トレースと関連付けて全体像を把握できます - ⚡ ユーザーフィードバック — アプリからユーザーが直接送信したバグレポートを収集します
推奨ロジック:
| 機能 | 推奨するタイミング |
|---|---|
| エラーモニタリング | 常に — すべてのモバイルアプリに欠かせない基本機能です |
| トレーシング | モバイルでは常に — アプリ起動、ナビゲーション、ネットワークの遅延が重要です |
| セッションリプレイ | ユーザー向けの本番アプリで、ユーザーから報告された問題を視覚的にデバッグする場合 |
| プロファイリング | パフォーマンスが重要な画面、起動時間に関する懸念、または本番環境でのパフォーマンス調査がある場合 |
| ロギング | アプリで構造化ログを使用している場合、または Sentry でログとトレースを関連付けたい場合 |
| ユーザーフィードバック | ユーザーから送信されたバグレポートを収集したいベータ版または顧客向けアプリの場合 |
次のように提案します。「お使いの [Expo managed/bare RN] アプリには、エラーモニタリング + トレーシング + セッションリプレイのセットアップをおすすめします。プロファイリングとロギングも追加しましょうか?」
フェーズ 3:案内
セットアップ手順を判断する
| プロジェクトの種類 | 推奨セットアップ | 複雑さ |
|---|---|---|
| Expo managed(SDK 50+) | ウィザード CLI、または設定プラグインを使用した手動セットアップ | 低 — ウィザードがすべて処理します |
| Expo bare(SDK 50+) | ウィザード CLI を推奨 | 中 — iOS/Android の設定を処理します |
| Vanilla React Native(0.69+) | ウィザード CLI を推奨 | 中 — Xcode + Gradle を処理します |
| Expo SDK <50 | sentry-expo(レガシー)を使用 | レガシードキュメントを参照してください |
パス A:ウィザード CLI(すべてのプロジェクトタイプにおすすめ)
ウィザードを実行します。ログイン、組織/プロジェクトの選択、認証トークンの設定を対話形式で進められます。その後、インストール、ネイティブ設定、ソースマップのアップロード、初期の Sentry.init() の設定を行います:
npx @sentry/wizard@latest -i reactNative
ウィザードが作成/変更するファイル:
| ファイル | 操作 | 目的 |
|---|---|---|
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 | org/project/token を保存 | iOS のソースマップと dSYM のアップロード |
android/sentry.properties | org/project/token を保存 | Android のソースマップのアップロード |
android/app/build.gradle | Sentry Gradle プラグインを追加 | Android のソースマップと ProGuard |
ios/[AppName].xcodeproj | 「Bundle RN」ビルドフェーズをラップし、dSYM のアップロードを追加 | iOS シンボルのアップロード |
.env.local | SENTRY_AUTH_TOKEN | 認証トークン(.gitignore に追加してください) |
ウィザードの実行後は、検証に進んでください。
パス B:手動 — Expo Managed(SDK 50+)
ステップ 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
# Then replace contents with the above
ステップ 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(), // 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);
標準の 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);
パス C:手動 — Bare React Native(0.69+)
ステップ 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 ビルドフェーズを追加します(バンドルフェーズの後):
/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);
}}
>
{/* your navigation here */}
</NavigationContainer>
);
}
export default Sentry.wrap(App);
クイックリファレンス:すべての機能を有効にした Sentry.init()
以下は、すべての機能を有効にした推奨の初期設定です:
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: "[email protected]+1",
// dist: "1",
});
// REQUIRED: Wrap root component to capture React render errors
export default Sentry.wrap(App);
ナビゲーションの設定 — React Navigation(v5+)
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);
}}
>
ナビゲーションの設定 — Wix React Native Navigation
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);
合意した機能ごとに設定
機能を一度に 1 つずつ設定します。それぞれのリファレンスファイルを読み込み、手順に従ってから、次に進む前に検証してください:
| 機能 | リファレンス | 読み込むタイミング |
|---|---|---|
| エラーモニタリング | ${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 | ユーザーからの報告を収集する場合 |
各機能について、Read ${SKILL_ROOT}/references/<feature>.md を読み、手順に正確に従い、動作を検証してください。
設定リファレンス
コアのSentry.init()オプション
| オプション | 型 | デフォルト | 目的 |
|---|---|---|---|
dsn | string | — | 必須。 プロジェクト DSN。空の場合、SDK は無効になります。環境変数:SENTRY_DSN |
environment | string | — | 例:"production"、"staging"。環境変数:SENTRY_ENVIRONMENT |
release | string | — | アプリのバージョン。例:"[email protected]+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)[] | [/.*/] | 分散トレーシングヘッダーを付与する API URL |
profilesSampleRate | number | 0 | プロファイリングのサンプルレート(トレース対象のトランザクションに適用) |
ネイティブ/モバイルオプション
| オプション | 型 | デフォルト | 目的 |
|---|---|---|---|
enableNative | boolean | true | JS のみ(ネイティブ SDK なし)にするには、falseを設定します |
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 | ネイティブ SDK を手動で初期化するには、falseを設定します |
onReady | function | — | ネイティブ SDK の初期化後に実行されるコールバック |
セッションとリリースヘルスのオプション
| オプション | 型 | デフォルト | 目的 |
|---|---|---|---|
autoSessionTracking | boolean | true | セッションを追跡します(クラッシュのないユーザー/セッション) |
sessionTrackingIntervalMillis | number | 30000 | セッションが終了するまでのバックグラウンド時間(ミリ秒) |
リプレイオプション
| オプション | 型 | デフォルト | 目的 |
|---|---|---|---|
replaysSessionSampleRate | number | 0 | 記録する全セッションの割合 |
replaysOnErrorSampleRate | number | 0 | 記録するエラー発生セッションの割合 |
ロギングオプション(SDK ≥7.0.0)
| オプション | 型 | 目的 |
|---|---|---|
enableLogs | boolean | Sentry.logger.* API を有効にします |
beforeSendLog | function | 送信前にログをフィルタリング/変更します |
logsOrigin | 'native' | 'js' | 'all' | ログの送信元をフィルタリングします(SDK ≥7.7.0) |
フックのオプション
| オプション | 型 | 用途 |
|---|---|---|
beforeSend | (event, hint) => event | null | JavaScript エラーイベントを変更または破棄します。⚠️ ネイティブクラッシュには適用されません |
beforeSendTransaction | (event) => event | null | トランザクションイベントを変更または破棄します |
beforeBreadcrumb | (breadcrumb, hint) => breadcrumb | null | 保存前にパンくずを処理します |
環境変数
| 変数 | 用途 | 備考 |
|---|---|---|
SENTRY_DSN | データソース名 | dsn オプションの代替として使用されます |
SENTRY_AUTH_TOKEN | ソースマップと dSYM をアップロードします | 絶対にコミットせず、CI シークレットを使用してください |
SENTRY_ORG | 組織のスラッグ | ウィザードとビルドプラグインで使用されます |
SENTRY_PROJECT | プロジェクトのスラッグ | ウィザードとビルドプラグインで使用されます |
SENTRY_RELEASE | リリース識別子 | release オプションの代替として使用されます |
SENTRY_ENVIRONMENT | 環境名 | environment オプションの代替として使用されます |
SENTRY_DISABLE_AUTO_UPLOAD | ソースマップのアップロードをスキップします | ローカルビルド中は true に設定します |
EXPO_PUBLIC_SENTRY_DSN | DSN 用の Expo 公開環境変数 | クライアントバンドルに安全に埋め込めます |
ソースマップとデバッグシンボル
ソースマップとデバッグシンボルを使うと、難読化されたスタックトレースを読みやすい形に変換できます。正しく設定すると、Sentry でエラーが発生したソースコードの正確な行を確認できます。
アップロードの仕組み
| プラットフォーム | アップロードされるもの | タイミング |
|---|---|---|
| iOS(JS) | ソースマップ(.map ファイル) | Xcode ビルド中 |
| iOS(ネイティブ) | dSYM バンドル | Xcode アーカイブ / Xcode Cloud 中 |
| Android(JS) | ソースマップ + Hermes .hbc.map | Gradle ビルド中 |
| Android(ネイティブ) | Proguard マッピング + NDK .so ファイル | Gradle ビルド中 |
Expo:自動アップロード
@sentry/react-native/expo 設定プラグインは、ネイティブビルド用のアップロードフックを自動的に設定します。eas build および expo run:ios/android(リリース)中にソースマップがアップロードされます。
SENTRY_AUTH_TOKEN=sntrys_... npx expo run:ios --configuration Release
手動アップロード(bare RN)
ソースマップを手動でアップロードする必要がある場合:
npx sentry-cli sourcemaps upload \
--org YOUR_ORG \
--project YOUR_PROJECT \
--release "[email protected]+1" \
./dist
デフォルトのインテグレーション(自動有効化)
以下のインテグレーションは自動的に有効になります。設定は不要です。
| インテグレーション | 機能 |
|---|---|
ReactNativeErrorHandlers | 未処理の JavaScript 例外と Promise の拒否を捕捉します |
Release | すべてのイベントにリリース / dist を付与します |
Breadcrumbs | コンソールログ、HTTP リクエスト、ユーザー操作をパンくずとして記録します |
HttpClient | HTTP リクエスト / レスポンスのパンくずを追加します |
DeviceContext | デバイス / OS / バッテリー情報をイベントに付与します |
AppContext | アプリのバージョン、バンドル ID、メモリ情報を付与します |
CultureContext | ロケールとタイムゾーンを付与します |
Screenshot | エラー発生時にスクリーンショットを取得します(attachScreenshot: true の場合) |
ViewHierarchy | ビューハイラルキーを付与します(attachViewHierarchy: true の場合) |
NativeLinkedErrors | JavaScript エラーを対応するネイティブクラッシュに関連付けます |
オプトインのインテグレーション
| インテグレーション | 有効にする方法 |
|---|---|
mobileReplayIntegration() | integrations 配列に追加します |
reactNavigationIntegration() | integrations 配列に追加します |
reactNativeNavigationIntegration() | integrations 配列に追加します(Wix 専用) |
feedbackIntegration() | integrations 配列に追加します(ユーザーフィードバックウィジェット) |
Expo 設定プラグインのリファレンス
app.json または 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"
}
]
]
}
}
または、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.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__,
});
検証
セットアップ後、Sentry がイベントを受信していることをテストします。
// 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");
}}
/>
Sentry ダッシュボードを確認します。
- Issues → テストエラーが数秒以内に表示されます
- Traces → 子スパンを含む「main」トランザクションを確認します
- Replays → アプリを操作した後にセッションの記録が表示されます(ネイティブビルドのみ。Expo Go では利用できません)
- Logs →
enableLogs: trueの場合、構造化ログエントリーが表示されます
⚠️ Expo Go の制限事項: ネイティブクラッシュ、セッションリプレイ、遅い/フリーズしたフレーム、TTID、TTFD はネイティブビルド(
eas buildまたはexpo run)でのみ動作します。Expo Go は JS のみのモードで実行されます。警告を避けるには、enableNativeFramesTracking: !isRunningInExpoGo()を設定してください。
何も表示されない場合:
debug: trueを設定します。SDK のログが Metro コンソールに出力されます- DSN が正しく、Sentry プロジェクトが存在することを確認します
- ルートコンポーネントに
Sentry.wrap(App)が適用されていることを確認します - ネイティブクラッシュの場合は、リリースビルドを作成します(デバッグモードでのクラッシュは転送されない場合があります)
フェーズ 4:相互リンク
React Native のセットアップが完了したら、Sentry のカバレッジがないバックエンドまたは Web フロントエンドがないか確認します。
# 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
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/ を参照 |
| React / Next.js Web | sentry-react-sdk |
| Svelte / SvelteKit Web | sentry-svelte-sdk |
分散トレーシングのセットアップ — バックエンドのスキルが追加された場合は、トレースコンテキストを API に伝播するよう、React Native で tracePropagationTargets を設定します。
Sentry.init({
tracePropagationTargets: [
"localhost",
/^https:\/\/api\.yourapp\.com/,
],
// ...
});
これにより、Sentry のウォーターフォールビューでモバイルのトランザクションとバックエンドのトレースが関連付けられます。
トラブルシューティング
| 問題 | 解決策 |
|---|---|
| Sentry にイベントが表示されない | debug: true を設定し、Metro/Xcode コンソールで SDK エラーを確認します。DSN が正しいことを確認します |
pod install が失敗する | cd ios && pod install --repo-update を実行し、CocoaPods のバージョンを確認します |
| Sentry スクリプトが原因で iOS ビルドが失敗する | 「Bundle React Native code and images」スクリプトが追記ではなく置き換えられていることを確認します |
sentry.gradle の追加後に Android ビルドが失敗する | build.gradle の android {} ブロックより前に apply from の行があることを確認します |
| Android Gradle 8 以降との互換性の問題 | sentry-android-gradle-plugin ≥4.0.0 を使用し、SDK 内の sentry.gradle のバージョンを確認します |
| ソースマップがアップロードされない | sentry.properties に有効な auth.token があることを確認し、ビルドログで sentry-cli の出力を確認します |
| Sentry でソースマップが解決されない | Sentry.init() の release と dist が、アップロードしたバンドルのメタデータと一致することを確認します |
| Hermes のソースマップが機能しない | Hermes は .hbc.map を生成します。Gradle プラグインが自動的に処理するため、sentry.gradle が適用されていることを確認します |
| セッションリプレイが記録されない | ネイティブビルドを使用する必要があります(Expo Go は不可)。integrations に mobileReplayIntegration() が含まれていることを確認します |
| リプレイ画面が空白または黒く表示される | maskAllText/maskAllImages の設定がプライバシー要件に合っていることを確認します |
| 遅いフレームやフリーズしたフレームが追跡されない | enableNativeFramesTracking: true を設定し、ネイティブビルドを使用していることを確認します(Expo Go は不可) |
| TTID/TTFD が表示されない | ネイティブビルドで reactNavigationIntegration() に enableTimeToInitialDisplay: true を設定する必要があります |
| Sentry の追加後、アプリが起動時にクラッシュする | ネイティブの初期化エラーが原因と考えられます。Xcode/Logcat のログを確認し、切り分けのために enableNative: false を試します |
| Expo SDK 49 以前 | sentry-expo(旧パッケージ)を使用します。@sentry/react-native には Expo SDK 50 以降が必要です |
isRunningInExpoGo のインポートエラー | expo パッケージからインポートします:import { isRunningInExpoGo } from "expo" |
| Xcode ビルド中に Node が見つからない | Xcode のビルドフェーズに export NODE_BINARY=$(which node) を追加するか、シンボリックリンクを作成します:ln -s $(which node) /usr/local/bin/node |
| Expo Go がネイティブ機能に関する警告を表示する | isRunningInExpoGo() ガードを使用します:enableNativeFramesTracking: !isRunningInExpoGo() |
ネイティブクラッシュで beforeSend が実行されない | 想定どおりの動作です。beforeSend が捕捉するのは JS レイヤーのエラーのみで、ネイティブクラッシュには適用されません |
| Android 15 以降(16 KB ページサイズ)でクラッシュする | @sentry/react-native を ≥6.3.0 にアップグレードします |
| ダッシュボードに表示されるトランザクションが多すぎる | tracesSampleRate を 0.1 に下げるか、tracesSampler を使用してヘルスチェックを除外します |
アプリバンドル内に SENTRY_AUTH_TOKEN が含まれる | SENTRY_AUTH_TOKEN はビルド時のアップロード専用です。Sentry.init() に渡さないでください |
| EAS Build で Sentry 認証トークンが見つからない | SENTRY_AUTH_TOKEN を EAS シークレットとして設定します:eas secret:create --name SENTRY_AUTH_TOKEN |