react-native.tsx 12 KB

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