react-native.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. import {Fragment} from 'react';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import List from 'sentry/components/list/';
  4. import ListItem from 'sentry/components/list/listItem';
  5. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  6. import type {
  7. Docs,
  8. DocsParams,
  9. OnboardingConfig,
  10. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  11. import {
  12. getCrashReportApiIntroduction,
  13. getCrashReportInstallDescription,
  14. } from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding';
  15. import {getReactNativeMetricsOnboarding} from 'sentry/components/onboarding/gettingStartedDoc/utils/metricsOnboarding';
  16. import {t, tct} from 'sentry/locale';
  17. type Params = DocsParams;
  18. const getConfigureSnippet = (params: Params) => `
  19. import * as Sentry from "@sentry/react-native";
  20. Sentry.init({
  21. dsn: "${params.dsn}",
  22. // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
  23. // We recommend adjusting this value in production.
  24. tracesSampleRate: 1.0,
  25. });`;
  26. const getPerformanceSnippet = () => `
  27. // Let's say this function is invoked when a user clicks on the checkout button of your shop
  28. shopCheckout() {
  29. // This will create a new Transaction for you
  30. const transaction = Sentry.startTransaction({ name: "shopCheckout" });
  31. // Set transaction on scope to associate with errors and get included span instrumentation
  32. // If there's currently an unfinished transaction, it may be dropped
  33. Sentry.getCurrentHub().configureScope(scope => scope.setSpan(transaction));
  34. // Assume this function makes an xhr/fetch call
  35. const result = validateShoppingCartOnServer();
  36. const span = transaction.startChild({
  37. data: {
  38. result
  39. },
  40. op: 'task',
  41. description: "processing shopping cart result",
  42. });
  43. try {
  44. processAndValidateShoppingCart(result);
  45. span.setStatus(SpanStatus.Ok);
  46. } catch (err) {
  47. span.setStatus(SpanStatus.UnknownError);
  48. throw err;
  49. } finally {
  50. span.finish();
  51. transaction.finish();
  52. }
  53. }`;
  54. const onboarding: OnboardingConfig = {
  55. install: () => [
  56. {
  57. type: StepType.INSTALL,
  58. description: tct(
  59. 'Sentry captures data by using an SDK within your application’s runtime. If you are using Expo, see [expoLink:How to Add Sentry to Your Expo Project]. This SDK works for both managed and bare projects.',
  60. {expoLink: <ExternalLink href="https://docs.expo.dev/guides/using-sentry/" />}
  61. ),
  62. configurations: [
  63. {
  64. language: 'bash',
  65. description: <div>{tct('Run [code:@sentry/wizard]:', {code: <code />})}</div>,
  66. code: 'npx @sentry/wizard@latest -s -i reactNative',
  67. additionalInfo: (
  68. <Fragment>
  69. <p>
  70. {tct(
  71. '[wizardLink:Sentry Wizard] will patch your project accordingly, though you can [setupManuallyLink:setup manually] if you prefer.',
  72. {
  73. wizardLink: (
  74. <ExternalLink href="https://github.com/getsentry/sentry-wizard" />
  75. ),
  76. setupManuallyLink: (
  77. <ExternalLink href="https://docs.sentry.io/platforms/react-native/manual-setup/manual-setup/" />
  78. ),
  79. }
  80. )}
  81. </p>
  82. <List symbol="bullet">
  83. <ListItem>
  84. {t(
  85. 'iOS Specifics: When you use Xcode, you can hook directly into the build process to upload debug symbols and source maps.'
  86. )}
  87. </ListItem>
  88. <ListItem>
  89. {tct(
  90. "Android Specifics: We hook into Gradle for the source map build process. When you run [gradLewCode:./gradlew] assembleRelease, source maps are automatically built and uploaded to Sentry. If you have enabled Gradle's [orgGradleCode:org.gradle.configureondemand] feature, you'll need a clean build, or you'll need to disable this feature to upload the source map on every build by setting [orgGradleCodeConfigureCode:org.gradle.configureondemand=false] or remove it.",
  91. {
  92. gradLewCode: <code />,
  93. orgGradleCode: <code />,
  94. orgGradleCodeConfigureCode: <code />,
  95. }
  96. )}
  97. </ListItem>
  98. </List>
  99. </Fragment>
  100. ),
  101. },
  102. ],
  103. },
  104. ],
  105. configure: params => [
  106. {
  107. type: StepType.CONFIGURE,
  108. configurations: [
  109. {
  110. language: 'javascript',
  111. code: getConfigureSnippet(params),
  112. additionalInfo: tct(
  113. 'The "sentry-wizard" will try to add it to your [code:App.tsx]',
  114. {
  115. code: <code />,
  116. }
  117. ),
  118. },
  119. {
  120. language: 'javascript',
  121. description: tct(
  122. 'Wrap your app with Sentry to automatically instrument it with [touchEventTrakingLink:touch event tracking] and [automaticPerformanceMonitoringLink:automatic performance monitoring]:',
  123. {
  124. touchEventTrakingLink: (
  125. <ExternalLink href="https://docs.sentry.io/platforms/react-native/touchevents/" />
  126. ),
  127. automaticPerformanceMonitoringLink: (
  128. <ExternalLink href="https://docs.sentry.io/platforms/react-native/performance/instrumentation/automatic-instrumentation/" />
  129. ),
  130. }
  131. ),
  132. code: 'export default Sentry.wrap(App);',
  133. additionalInfo: t(
  134. 'You do not need to do this for Sentry to work or if your app does not have a single parent "App" component.'
  135. ),
  136. },
  137. ],
  138. },
  139. ],
  140. verify: () => [
  141. {
  142. type: StepType.VERIFY,
  143. description: t(
  144. 'Then create an intentional error, so you can test that everything is working:'
  145. ),
  146. configurations: [
  147. {
  148. language: 'javascript',
  149. code: "throw new Error('My first Sentry error!');",
  150. },
  151. {
  152. language: 'javascript',
  153. description: t('Or, try a native crash with:'),
  154. code: 'Sentry.nativeCrash();',
  155. additionalInfo: (
  156. <Fragment>
  157. {t(
  158. "If you're new to Sentry, use the email alert to access your account and complete a product tour."
  159. )}
  160. {t(
  161. "If you're an existing user and have disabled alerts, you won't receive this email."
  162. )}
  163. </Fragment>
  164. ),
  165. },
  166. ],
  167. },
  168. {
  169. title: t('Performance'),
  170. description: (
  171. <Fragment>
  172. {t(
  173. 'Sentry can measure the performance of your app automatically when instrumented with the following routers:'
  174. )}
  175. <List symbol="bullet">
  176. <ListItem>
  177. <ExternalLink href="https://docs.sentry.io/platforms/react-native/performance/instrumentation/automatic-instrumentation/#react-navigation">
  178. {t('React Navigation')}
  179. </ExternalLink>
  180. </ListItem>
  181. <ListItem>
  182. <ExternalLink href="https://docs.sentry.io/platforms/react-native/performance/instrumentation/automatic-instrumentation/#react-navigation-v4">
  183. {t('React Navigation V4 and prior')}
  184. </ExternalLink>
  185. </ListItem>
  186. <ListItem>
  187. <ExternalLink href="https://docs.sentry.io/platforms/react-native/performance/instrumentation/automatic-instrumentation/#react-native-navigation">
  188. {t('React Native Navigation')}
  189. </ExternalLink>
  190. </ListItem>
  191. </List>
  192. {t('Additionally, you can create transactions and spans programatically:')}
  193. </Fragment>
  194. ),
  195. configurations: [
  196. {
  197. description: t('For example:'),
  198. language: 'javascript',
  199. code: getPerformanceSnippet(),
  200. additionalInfo: tct(
  201. 'For more information, please refer to the [docLink: Sentry React Native documentation].',
  202. {
  203. docLink: (
  204. <ExternalLink href="https://docs.sentry.io/platforms/react-native/performance/instrumentation/" />
  205. ),
  206. }
  207. ),
  208. },
  209. ],
  210. },
  211. {
  212. title: t('Debug Symbols'),
  213. description: (
  214. <Fragment>
  215. {t(
  216. 'We offer a range of methods to provide Sentry with debug symbols so that you can see symbolicated stack traces and triage issues faster.'
  217. )}
  218. <p>
  219. {tct(
  220. "Complete stack traces will be shown for React Native Javascript errors by default using Sentry's [automaticSourceMapsUploadLink:automatic source maps upload]. To set up manual source maps upload follow [guideLink:this guide].",
  221. {
  222. automaticSourceMapsUploadLink: (
  223. <ExternalLink href="https://docs.sentry.io/platforms/react-native/sourcemaps/" />
  224. ),
  225. guideLink: (
  226. <ExternalLink href="https://docs.sentry.io/platforms/react-native/sourcemaps/" />
  227. ),
  228. }
  229. )}
  230. </p>
  231. <p>
  232. {tct(
  233. "You'll also need to upload [debugSymbolsLink:Debug Symbols] generated by the native iOS and Android tooling for native crashes.",
  234. {
  235. debugSymbolsLink: (
  236. <ExternalLink href="https://docs.sentry.io/platforms/react-native/upload-debug/" />
  237. ),
  238. }
  239. )}
  240. </p>
  241. </Fragment>
  242. ),
  243. },
  244. {
  245. title: t('Source Context'),
  246. description: (
  247. <Fragment>
  248. <p>
  249. {tct(
  250. "If Sentry has access to your application's source code, it can show snippets of code [italic:(source context)] around the location of stack frames, which helps to quickly pinpoint problematic code.",
  251. {
  252. italic: <i />,
  253. }
  254. )}
  255. </p>
  256. <p>
  257. {tct(
  258. 'Source Context will be shown for React Native Javascript error by default if source maps are uploaded. To set up source maps upload, follow the [sourceMapsGuideLink:Source Maps guide].',
  259. {
  260. sourceMapsGuideLink: (
  261. <ExternalLink href="https://docs.sentry.io/platforms/react-native/sourcemaps/" />
  262. ),
  263. }
  264. )}
  265. </p>
  266. <p>
  267. {tct(
  268. "To enable source context for native errors, you'll need to upload native debug symbols to Sentry by following the instructions at [uploadWithGradleLink:Uploading Source Code Context With Sentry Gradle Plugin] and Uploading Source Context With Xcode.",
  269. {
  270. uploadWithGradleLink: (
  271. <ExternalLink href="https://docs.sentry.io/platforms/react-native/upload-debug/#uploading-source-context-with-sentry-gradle-plugin" />
  272. ),
  273. uploadWithXCodeLink: (
  274. <ExternalLink href="https://docs.sentry.io/platforms/react-native/upload-debug/#uploading-source-context-with-xcode" />
  275. ),
  276. }
  277. )}
  278. </p>
  279. </Fragment>
  280. ),
  281. },
  282. ],
  283. };
  284. const feedbackOnboardingCrashApi: OnboardingConfig = {
  285. introduction: () => getCrashReportApiIntroduction(),
  286. install: () => [
  287. {
  288. type: StepType.INSTALL,
  289. description: getCrashReportInstallDescription(),
  290. configurations: [
  291. {
  292. code: [
  293. {
  294. label: 'TypeScript',
  295. value: 'typescript',
  296. language: 'typescript',
  297. code: `import * as Sentry from "@sentry/react-native";
  298. import { UserFeedback } from "@sentry/react-native";
  299. const sentryId = Sentry.captureMessage("My Message");
  300. // OR: const sentryId = Sentry.lastEventId();
  301. const userFeedback: UserFeedback = {
  302. event_id: sentryId,
  303. name: "John Doe",
  304. email: "john@doe.com",
  305. comments: "Hello World!",
  306. };
  307. Sentry.captureUserFeedback(userFeedback);`,
  308. },
  309. ],
  310. },
  311. ],
  312. },
  313. ],
  314. configure: () => [],
  315. verify: () => [],
  316. nextSteps: () => [],
  317. };
  318. const getInstallConfig = () => [
  319. {
  320. language: 'bash',
  321. code: [
  322. {
  323. label: 'npm',
  324. value: 'npm',
  325. language: 'bash',
  326. code: 'npm install --save @sentry/react-native',
  327. },
  328. {
  329. label: 'yarn',
  330. value: 'yarn',
  331. language: 'bash',
  332. code: 'yarn add @sentry/react-native',
  333. },
  334. ],
  335. },
  336. ];
  337. const docs: Docs = {
  338. onboarding,
  339. feedbackOnboardingCrashApi,
  340. crashReportOnboarding: feedbackOnboardingCrashApi,
  341. customMetricsOnboarding: getReactNativeMetricsOnboarding({getInstallConfig}),
  342. };
  343. export default docs;