Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 49 additions & 49 deletions skills/sentry-react-native-sdk/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ npx expo customize metro.config.js
{
"url": "https://sentry.io/",
"project": "YOUR_PROJECT_SLUG",
"organization": "YOUR_ORG_SLUG"
"organization": "YOUR_ORG_SLUG",
"disableAutoUpload": false
}
]
]
Expand All @@ -189,19 +190,23 @@ npx expo customize metro.config.js

> **Note:** Set `SENTRY_AUTH_TOKEN` as an environment variable for native builds — never commit it to version control.

**Plugin options:**

| Option | Type | Default | Purpose |
|--------|------|---------|---------|
| `url` | `string` | `"https://sentry.io/"` | Sentry instance URL |
| `project` | `string` | — | Project slug |
| `organization` | `string` | — | Organization slug |
| `disableAutoUpload` | `boolean` | `false` | Skip source map + dSYM upload during local builds (SDK ≥8.13.0) |

**Step 4 — Initialize Sentry**

For **Expo Router** (`app/_layout.tsx`):

```typescript
import { Stack, useNavigationContainerRef } from "expo-router";
import { Stack } 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",
Expand All @@ -220,9 +225,8 @@ Sentry.init({
// Logging (SDK ≥7.0.0)
enableLogs: true,

// Navigation
// Session Replay
integrations: [
navigationIntegration,
Sentry.mobileReplayIntegration(),
],

Expand All @@ -232,31 +236,20 @@ Sentry.init({
});

function RootLayout() {
const ref = useNavigationContainerRef();

React.useEffect(() => {
if (ref) {
navigationIntegration.registerNavigationContainer(ref);
}
}, [ref]);

return <Stack />;
}

export default Sentry.wrap(RootLayout);
```

> **Note:** Expo Router automatically handles navigation tracking. The `Sentry.NavigationContainer` wrapper is not needed for Expo Router projects — navigation spans are captured automatically.

For **standard Expo** (`App.tsx`):

```typescript
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,
Expand All @@ -266,25 +259,17 @@ Sentry.init({
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);
}}
>
<Sentry.NavigationContainer>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Documentation suggests using <Sentry.NavigationContainer>, which will crash on supported SDK versions older than 8.13.0 where the component doesn't exist.
Severity: HIGH

Suggested Fix

Add a version caveat (e.g., "SDK ≥8.13.0 only") directly in the main setup examples where <Sentry.NavigationContainer> is used. Alternatively, use the manual <NavigationContainer ref={...}> approach in the main examples and present <Sentry.NavigationContainer> as a version-specific alternative.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: skills/sentry-react-native-sdk/SKILL.md#L270

Potential issue: The setup guide in `SKILL.md` recommends using
`<Sentry.NavigationContainer>` in its main examples for both standard Expo and bare
React Native. However, the documentation's minimum recommended SDK is `≥8.0.0`, while
the `<Sentry.NavigationContainer>` component only exists in SDK versions `≥8.13.0`.
Developers on SDK versions between 8.0.0 and 8.12.x who follow these setup instructions
will encounter a runtime `TypeError` crash because the component will be undefined.
While a version caveat exists in a separate section, its absence from the main setup
paths creates a trap for users.

Did we get this right? 👍 / 👎 to inform future reviews.

{/* your navigation here */}
</NavigationContainer>
</Sentry.NavigationContainer>
);
}

Expand Down Expand Up @@ -351,9 +336,11 @@ auth.token=YOUR_ORG_AUTH_TOKEN
Add before the `android {}` block:

```groovy
apply from: "../../node_modules/@sentry/react-native/sentry.gradle"
apply from: "../../node_modules/@sentry/react-native/sentry.gradle.kts"
```

> **Note:** SDK ≥8.13.0 uses `sentry.gradle.kts` (Kotlin DSL). For older SDKs, use `sentry.gradle` (Groovy). Both are backward-compatible.

**Step 7 — Android: `android/sentry.properties`**

```properties
Expand All @@ -366,13 +353,8 @@ auth.token=YOUR_ORG_AUTH_TOKEN
**Step 8 — Initialize Sentry (`App.tsx` or entry point)**

```typescript
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,
Expand All @@ -382,25 +364,17 @@ Sentry.init({
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);
}}
>
<Sentry.NavigationContainer>
{/* your navigation here */}
</NavigationContainer>
</Sentry.NavigationContainer>
);
}

Expand Down Expand Up @@ -475,6 +449,29 @@ If you don't call `Sentry.appLoaded()`, the SDK estimates the app start end auto

### Navigation Setup — React Navigation (v5+)

**Recommended: Use `Sentry.NavigationContainer` wrapper (SDK ≥8.13.0)**

Drop-in replacement for `NavigationContainer` that automatically wires up navigation tracking:

```typescript
import * as Sentry from "@sentry/react-native";

// Replace NavigationContainer with Sentry.NavigationContainer
<Sentry.NavigationContainer>
<Stack.Navigator>
{/* your screens */}
</Stack.Navigator>
</Sentry.NavigationContainer>
```

That's it! The wrapper automatically:
- Creates the `reactNavigationIntegration`
- Registers the navigation container ref
- Captures breadcrumbs for navigation events (SDK ≥8.13.0)
- Tracks Time to Initial Display (TTID) per screen

**Alternative: Manual setup (for SDK <8.13.0 or custom config)**

```typescript
import { reactNavigationIntegration } from "@sentry/react-native";
import { NavigationContainer, createNavigationContainerRef } from "@react-navigation/native";
Expand Down Expand Up @@ -780,13 +777,16 @@ export default {
url: "https://sentry.io/",
project: process.env.SENTRY_PROJECT,
organization: process.env.SENTRY_ORG,
disableAutoUpload: process.env.NODE_ENV === "development",
},
],
],
},
};
```

> **Tip:** Set `disableAutoUpload: true` during local development to speed up builds by skipping source map and dSYM uploads. The option is available in SDK ≥8.13.0.

---

## EAS Build Hooks
Expand Down Expand Up @@ -948,7 +948,7 @@ This links mobile transactions to backend traces in the Sentry waterfall view.
| 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` |
| Android build fails after adding `sentry.gradle.kts` | Ensure `apply from` line is before the `android {}` block in `build.gradle`; use `sentry.gradle` for SDK <8.13.0 |
| 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 |
Expand Down