Skip to content

Commit 8063938

Browse files
committed
feat(docs): add sentry setup
1 parent f17813e commit 8063938

File tree

2 files changed

+313
-0
lines changed

2 files changed

+313
-0
lines changed

docs/astro.config.mjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,16 @@ export default defineConfig({
151151
},
152152
],
153153
},
154+
{
155+
label: 'Recipes',
156+
items: [
157+
// Each item here is one entry in the navigation menu.
158+
{
159+
label: 'Sentry Setup',
160+
link: '/recipes/sentry-setup/',
161+
},
162+
],
163+
},
154164
{
155165
label: 'Testing',
156166
items: [
Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
---
2+
title: Sentry Setup
3+
description: How to setup Sentry in your app.
4+
head:
5+
- tag: title
6+
content: Sentry Setup | React Native / Expo Starter
7+
---
8+
9+
import CodeBlock from '../../../components/code.astro';
10+
import { Steps } from '@astrojs/starlight/components';
11+
12+
Sentry is one of the most popular solution for error reporting in the javascript ecosystem and has a great integration with Expo, we have been using it for a while and it has been working very well.
13+
14+
The starter kit did not come with Sentry pre-configured, but it's very easy to setup and this guide will walk you through the process.
15+
16+
## Install and configure Sentry
17+
18+
<Steps>
19+
1. Create a new [Sentry account](https://sentry.io/signup/) if you don't have one already. Once logged in, create a new project for your React Native app.
20+
21+
2. During project creation, pay close attention to and note down the following important details:
22+
23+
- Organization slug
24+
- Project name
25+
- DSN
26+
27+
we will use those details next to configure the Sentry SDK in your app.
28+
29+
3. Now you need also to generate a new Auth Token so you can use it to upload source maps to Sentry. To generate a new Auth Token you need to go to Developer [Settings > Auth Tokens](https://sentry.io/settings/auth-tokens/) and create a new token.
30+
31+
- Copy and securely store the generated token. You'll need this for configuring source map uploads.
32+
33+
4. At this point, you should have the following environment variables that need to be added to your `.env` files:
34+
35+
```bash
36+
SENTRY_ORG=your_sentry_organization_slug
37+
SENTRY_PROJECT=your_sentry_project_name
38+
SENTRY_DSN=your_sentry_dsn
39+
```
40+
41+
:::note
42+
You can use the same Sentry configuration for all app variants (development, staging, production) as Sentry allows you to filter errors by app ID or package name in the dashboard. This simplifies setup and management while still providing the ability to distinguish between different environments.
43+
:::
44+
45+
It's crucial to add these variables to `env.js` for validation. `SENTRY_ORG` and `SENTRY_PROJECT` should be added as build-time variables, while `SENTRY_DSN` should be added as a client variable.
46+
47+
Update your `env.js` file as follows:
48+
49+
```js title='env.js'
50+
// ... existing imports and configurations
51+
52+
const client = z.object({
53+
// ... other client env vars
54+
SENTRY_DSN: z.string().min(1, 'SENTRY_DSN is required'),
55+
});
56+
57+
const buildTime = z.object({
58+
// ... other build-time env vars
59+
SENTRY_ORG: z.string().min(1, 'SENTRY_ORG is required'),
60+
SENTRY_PROJECT: z.string().min(1, 'SENTRY_PROJECT is required'),
61+
});
62+
63+
const _clientEnv = {
64+
// ... other client env vars
65+
SENTRY_DSN: process.env.SENTRY_DSN,
66+
};
67+
68+
const _buildTimeEnv = {
69+
// ... other build-time env vars
70+
SENTRY_ORG: process.env.SENTRY_ORG,
71+
SENTRY_PROJECT: process.env.SENTRY_PROJECT,
72+
};
73+
74+
// ... rest of the file
75+
```
76+
77+
:::note
78+
The `SENTRY_AUTH_TOKEN` should not be added to the `.env` file as it's sensitive information that shouldn't be exposed or pushed to version control. Instead, add it as an EAS secret using the [Expo dashboard](https://expo.dev/accounts/[account]/projects/[project]/secrets) or the EAS CLI:
79+
80+
```bash
81+
eas secret:create --scope your-project-name --name SENTRY_AUTH_TOKEN --value your-token-value --type string
82+
```
83+
84+
This ensures that your Sentry authentication token remains secure while still being accessible during the build process.
85+
:::
86+
87+
5. Now you can install the Sentry SDK in your project.
88+
89+
```bash
90+
npm install @sentry/react-native
91+
```
92+
93+
6. Add Sentry plugin config to your `app.config.ts` file.
94+
95+
```tsx title='app.config.ts'
96+
// rest of the file
97+
98+
import { ClientEnv, Env } from './env';
99+
100+
export default ({ config }: ConfigContext): ExpoConfig => ({
101+
...config,
102+
// rest of the config
103+
104+
plugins: [
105+
// rest of the plugins
106+
[
107+
'@sentry/react-native/expo',
108+
{
109+
url: 'https://sentry.io/',
110+
organization: Env.SENTRY_ORG,
111+
project: Env.SENTRY_PROJECT,
112+
note: 'Ensure you set the SENTRY_AUTH_TOKEN as an environment variable to authenticate with Sentry. Do not add it to the .env file. Instead, add it as an EAS secret or as an environment variable in your CI/CD pipeline for security.',
113+
// If you are using a self-hosted instance, update the value of the url property
114+
// to point towards your self-hosted instance. For example, https://self-hosted.example.com/.
115+
},
116+
],
117+
],
118+
});
119+
```
120+
121+
7. Update your metro config to inject debug ID intro your source maps
122+
123+
```js title='metro.config.js'
124+
/* eslint-env node */
125+
// this replaces `const { getDefaultConfig } = require('expo/metro-config');`
126+
const { getSentryExpoConfig } = require('@sentry/react-native/metro');
127+
const { withNativeWind } = require('nativewind/metro');
128+
129+
const config = getSentryExpoConfig(__dirname);
130+
131+
module.exports = withNativeWind(config, { input: './global.css' });
132+
```
133+
134+
8. Now you are ready to initialize Sentry in your app.
135+
Create a new file `src/core/sentry.ts` and add the following code:
136+
137+
```tsx title='src/core/sentry.ts'
138+
import { useNavigationContainerRef } from 'expo-router';
139+
import { useEffect } from 'react';
140+
import * as Sentry from '@sentry/react-native';
141+
import { Env } from '@env';
142+
143+
const routingInstrumentation = new Sentry.ReactNavigationInstrumentation();
144+
145+
export const initSentry = () => {
146+
Sentry.init({
147+
dsn: Env.SENTRY_DSN,
148+
// debug: Env.APP_ENV === 'development',
149+
integrations: [
150+
new Sentry.ReactNativeTracing({
151+
routingInstrumentation,
152+
enableNativeFramesTracking: true,
153+
// ...
154+
}),
155+
],
156+
});
157+
};
158+
159+
export const useSentryNavigationConfig = () => {
160+
const navigationRef = useNavigationContainerRef();
161+
162+
useEffect(() => {
163+
if (navigationRef) {
164+
routingInstrumentation.registerNavigationContainer(navigationRef);
165+
}
166+
}, [navigationRef]);
167+
};
168+
```
169+
170+
Then, initialize Sentry and configure it with navigation in your `src/app/_layout.tsx` file:
171+
172+
```tsx title='src/app/_layout.tsx'
173+
import { initSentry, useSentryNavigationConfig } from '@/core/sentry';
174+
import * as Sentry from '@sentry/react-native';
175+
176+
initSentry();
177+
178+
function RootLayout() {
179+
useSentryNavigationConfig();
180+
181+
return (
182+
<Providers>
183+
<Stack>
184+
<Stack.Screen name="(app)" options={{ headerShown: false }} />
185+
<Stack.Screen name="onboarding" options={{ headerShown: false }} />
186+
...
187+
</Stack>
188+
</Providers>
189+
);
190+
}
191+
192+
// Wrap your app with Sentry
193+
export default Sentry.wrap(RootLayout);
194+
```
195+
196+
This setup will enable Sentry error tracking and performance monitoring in your app.
197+
198+
9. One last thing is to add Apple privacy manifest to prevent any issues with Apple.
199+
Create a new file `apple-privacy-manifest.json` and add the following code:
200+
201+
```json title='apple-privacy-manifest.json'
202+
{
203+
"NSPrivacyCollectedDataTypes": [
204+
{
205+
"NSPrivacyCollectedDataType": "NSPrivacyCollectedDataTypeCrashData",
206+
"NSPrivacyCollectedDataTypeLinked": false,
207+
"NSPrivacyCollectedDataTypeTracking": false,
208+
"NSPrivacyCollectedDataTypePurposes": [
209+
"NSPrivacyCollectedDataTypePurposeAppFunctionality"
210+
]
211+
},
212+
{
213+
"NSPrivacyCollectedDataType": "NSPrivacyCollectedDataTypePerformanceData",
214+
"NSPrivacyCollectedDataTypeLinked": false,
215+
"NSPrivacyCollectedDataTypeTracking": false,
216+
"NSPrivacyCollectedDataTypePurposes": [
217+
"NSPrivacyCollectedDataTypePurposeAppFunctionality"
218+
]
219+
},
220+
{
221+
"NSPrivacyCollectedDataType": "NSPrivacyCollectedDataTypeOtherDiagnosticData",
222+
"NSPrivacyCollectedDataTypeLinked": false,
223+
"NSPrivacyCollectedDataTypeTracking": false,
224+
"NSPrivacyCollectedDataTypePurposes": [
225+
"NSPrivacyCollectedDataTypePurposeAppFunctionality"
226+
]
227+
}
228+
],
229+
"NSPrivacyAccessedAPITypes": [
230+
{
231+
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
232+
"NSPrivacyAccessedAPITypeReasons": ["CA92.1"]
233+
},
234+
{
235+
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategorySystemBootTime",
236+
"NSPrivacyAccessedAPITypeReasons": ["35F9.1"]
237+
},
238+
{
239+
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryFileTimestamp",
240+
"NSPrivacyAccessedAPITypeReasons": ["C617.1"]
241+
}
242+
]
243+
}
244+
```
245+
246+
Then add it to your `app.config.ts`
247+
248+
```ts title='app.config.ts'
249+
import applePrivacyManifest from './apple-privacy-manifest.json';
250+
export default ({ config }: ConfigContext): ExpoConfig => ({
251+
...config,
252+
// rest of the config
253+
ios: {
254+
// rest of ios config
255+
privacyManifests: applePrivacyManifest,
256+
},
257+
});
258+
```
259+
260+
Read more about [Apple Privacy Manifest and sentry](https://docs.sentry.io/platforms/react-native/data-management/apple-privacy-manifest/)
261+
262+
10. Now you are ready to test Sentry integration. Follow these steps to ensure errors are being reported correctly:
263+
264+
1. Run the prebuild command for your project.
265+
2. Launch the app in a simulator or on a physical device.
266+
3. Use the following code snippet to add error-triggering buttons to your app:
267+
268+
```tsx
269+
import React from 'react';
270+
import { View, Button } from 'react-native';
271+
import * as Sentry from '@sentry/react-native';
272+
273+
const SentryTestComponent = () => {
274+
const throwJSError = () => {
275+
throw new Error('Test JavaScript Error for Sentry');
276+
};
277+
278+
const triggerNativeError = () => {
279+
Sentry.nativeCrash();
280+
};
281+
282+
return (
283+
<View>
284+
<Button title="Trigger JS Error" onPress={throwJSError} />
285+
<Button title="Trigger Native Error" onPress={triggerNativeError} />
286+
</View>
287+
);
288+
};
289+
290+
export default SentryTestComponent;
291+
```
292+
293+
4. Implement this component in your app and interact with the buttons.
294+
5. Check your Sentry dashboard to verify that the errors are being reported correctly (make sure to wait a little bit for the errors to appear).
295+
296+
Remember to remove or disable these test buttons before releasing your app to production.
297+
298+
</Steps>
299+
300+
## More Resources
301+
302+
- [Expo Sentry](https://docs.expo.dev/guides/using-sentry/)
303+
- [Sentry Documentation](https://docs.sentry.io/platforms/react-native/manual-setup/expo/)

0 commit comments

Comments
 (0)