react.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. import {Fragment} from 'react';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import crashReportCallout from 'sentry/components/onboarding/gettingStartedDoc/feedback/crashReportCallout';
  4. import widgetCallout from 'sentry/components/onboarding/gettingStartedDoc/feedback/widgetCallout';
  5. import TracePropagationMessage from 'sentry/components/onboarding/gettingStartedDoc/replay/tracePropagationMessage';
  6. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  7. import type {
  8. Docs,
  9. DocsParams,
  10. OnboardingConfig,
  11. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  12. import {getUploadSourceMapsStep} from 'sentry/components/onboarding/gettingStartedDoc/utils';
  13. import {
  14. getCrashReportJavaScriptInstallStep,
  15. getCrashReportModalConfigDescription,
  16. getCrashReportModalIntroduction,
  17. getFeedbackConfigOptions,
  18. getFeedbackConfigureDescription,
  19. } from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding';
  20. import {getJSMetricsOnboarding} from 'sentry/components/onboarding/gettingStartedDoc/utils/metricsOnboarding';
  21. import {
  22. getProfilingDocumentHeaderConfigurationStep,
  23. MaybeBrowserProfilingBetaWarning,
  24. } from 'sentry/components/onboarding/gettingStartedDoc/utils/profilingOnboarding';
  25. import {
  26. getReplayConfigOptions,
  27. getReplayConfigureDescription,
  28. getReplayVerifyStep,
  29. } from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
  30. import {t, tct} from 'sentry/locale';
  31. type Params = DocsParams;
  32. const getSdkSetupSnippet = (params: Params) => `
  33. import * as Sentry from "@sentry/react";
  34. Sentry.init({
  35. dsn: "${params.dsn.public}",
  36. integrations: [${
  37. params.isPerformanceSelected
  38. ? `
  39. Sentry.browserTracingIntegration(),`
  40. : ''
  41. }${
  42. params.isProfilingSelected
  43. ? `
  44. Sentry.browserProfilingIntegration(),`
  45. : ''
  46. }${
  47. params.isFeedbackSelected
  48. ? `
  49. Sentry.feedbackIntegration({
  50. // Additional SDK configuration goes in here, for example:
  51. colorScheme: "system",
  52. ${getFeedbackConfigOptions(params.feedbackOptions)}}),`
  53. : ''
  54. }${
  55. params.isReplaySelected
  56. ? `
  57. Sentry.replayIntegration(${getReplayConfigOptions(params.replayOptions)}),`
  58. : ''
  59. }
  60. ],${
  61. params.isPerformanceSelected
  62. ? `
  63. // Tracing
  64. tracesSampleRate: 1.0, // Capture 100% of the transactions
  65. // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
  66. tracePropagationTargets: ["localhost", /^https:\\/\\/yourserver\\.io\\/api/],`
  67. : ''
  68. }${
  69. params.isProfilingSelected
  70. ? `
  71. // Set profilesSampleRate to 1.0 to profile every transaction.
  72. // Since profilesSampleRate is relative to tracesSampleRate,
  73. // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate
  74. // For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would
  75. // results in 25% of transactions being profiled (0.5*0.5=0.25)
  76. profilesSampleRate: 1.0,`
  77. : ''
  78. }${
  79. params.isReplaySelected
  80. ? `
  81. // Session Replay
  82. replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
  83. replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.`
  84. : ''
  85. }
  86. });
  87. const container = document.getElementById(“app”);
  88. const root = createRoot(container);
  89. root.render(<App />);
  90. `;
  91. const getVerifySnippet = () => `
  92. return <button onClick={() => {throw new Error("This is your first error!");}}>Break the world</button>;
  93. `;
  94. const getInstallConfig = () => [
  95. {
  96. language: 'bash',
  97. code: [
  98. {
  99. label: 'npm',
  100. value: 'npm',
  101. language: 'bash',
  102. code: 'npm install --save @sentry/react',
  103. },
  104. {
  105. label: 'yarn',
  106. value: 'yarn',
  107. language: 'bash',
  108. code: 'yarn add @sentry/react',
  109. },
  110. ],
  111. },
  112. ];
  113. const onboarding: OnboardingConfig = {
  114. introduction: params => (
  115. <Fragment>
  116. <MaybeBrowserProfilingBetaWarning {...params} />
  117. <p>
  118. {tct('In this quick guide you’ll use [strong:npm] or [strong:yarn] to set up:', {
  119. strong: <strong />,
  120. })}
  121. </p>
  122. </Fragment>
  123. ),
  124. install: () => [
  125. {
  126. type: StepType.INSTALL,
  127. description: tct(
  128. 'Add the Sentry SDK as a dependency using [code:npm] or [code:yarn]:',
  129. {code: <code />}
  130. ),
  131. configurations: getInstallConfig(),
  132. },
  133. ],
  134. configure: (params: Params) => [
  135. {
  136. type: StepType.CONFIGURE,
  137. description: t(
  138. "Initialize Sentry as early as possible in your application's lifecycle."
  139. ),
  140. configurations: [
  141. {
  142. code: [
  143. {
  144. label: 'JavaScript',
  145. value: 'javascript',
  146. language: 'javascript',
  147. code: getSdkSetupSnippet(params),
  148. },
  149. ],
  150. },
  151. ...(params.isProfilingSelected
  152. ? [getProfilingDocumentHeaderConfigurationStep()]
  153. : []),
  154. ],
  155. },
  156. getUploadSourceMapsStep({
  157. guideLink: 'https://docs.sentry.io/platforms/javascript/guides/react/sourcemaps/',
  158. ...params,
  159. }),
  160. ],
  161. verify: () => [
  162. {
  163. type: StepType.VERIFY,
  164. description: t(
  165. "This snippet contains an intentional error and can be used as a test to make sure that everything's working as expected."
  166. ),
  167. configurations: [
  168. {
  169. code: [
  170. {
  171. label: 'React',
  172. value: 'react',
  173. language: 'javascript',
  174. code: getVerifySnippet(),
  175. },
  176. ],
  177. },
  178. ],
  179. },
  180. ],
  181. nextSteps: () => [
  182. {
  183. id: 'react-features',
  184. name: t('React Features'),
  185. description: t('Learn about our first class integration with the React framework.'),
  186. link: 'https://docs.sentry.io/platforms/javascript/guides/react/features/',
  187. },
  188. {
  189. id: 'react-router',
  190. name: t('React Router'),
  191. description: t(
  192. 'Configure routing, so Sentry can generate parameterized transaction names for a better overview on the Performance page.'
  193. ),
  194. link: 'https://docs.sentry.io/platforms/javascript/guides/react/configuration/integrations/react-router/',
  195. },
  196. ],
  197. };
  198. const replayOnboarding: OnboardingConfig = {
  199. install: () => [
  200. {
  201. type: StepType.INSTALL,
  202. description: tct(
  203. 'Add the Sentry SDK as a dependency using [code:npm] or [code:yarn]. You need a minimum version 7.27.0 of [code:@sentry/react] in order to use Session Replay. You do not need to install any additional packages.',
  204. {code: <code />}
  205. ),
  206. configurations: getInstallConfig(),
  207. },
  208. ],
  209. configure: (params: Params) => [
  210. {
  211. type: StepType.CONFIGURE,
  212. description: getReplayConfigureDescription({
  213. link: 'https://docs.sentry.io/platforms/javascript/guides/react/session-replay/',
  214. }),
  215. configurations: [
  216. {
  217. code: [
  218. {
  219. label: 'JavaScript',
  220. value: 'javascript',
  221. language: 'javascript',
  222. code: getSdkSetupSnippet(params),
  223. },
  224. ],
  225. additionalInfo: <TracePropagationMessage />,
  226. },
  227. ],
  228. },
  229. ],
  230. verify: getReplayVerifyStep(),
  231. nextSteps: () => [],
  232. };
  233. const feedbackOnboarding: OnboardingConfig = {
  234. install: () => [
  235. {
  236. type: StepType.INSTALL,
  237. description: tct(
  238. 'For the User Feedback integration to work, you must have the Sentry browser SDK package, or an equivalent framework SDK (e.g. [code:@sentry/react]) installed, minimum version 7.85.0.',
  239. {
  240. code: <code />,
  241. }
  242. ),
  243. configurations: getInstallConfig(),
  244. },
  245. ],
  246. configure: (params: Params) => [
  247. {
  248. type: StepType.CONFIGURE,
  249. description: getFeedbackConfigureDescription({
  250. linkConfig:
  251. 'https://docs.sentry.io/platforms/javascript/guides/react/user-feedback/configuration/',
  252. linkButton:
  253. 'https://docs.sentry.io/platforms/javascript/guides/react/user-feedback/configuration/#bring-your-own-button',
  254. }),
  255. configurations: [
  256. {
  257. code: [
  258. {
  259. label: 'JavaScript',
  260. value: 'javascript',
  261. language: 'javascript',
  262. code: getSdkSetupSnippet(params),
  263. },
  264. ],
  265. },
  266. ],
  267. additionalInfo: crashReportCallout({
  268. link: 'https://docs.sentry.io/platforms/javascript/guides/react/user-feedback/#crash-report-modal',
  269. }),
  270. },
  271. ],
  272. verify: () => [],
  273. nextSteps: () => [],
  274. };
  275. const crashReportOnboarding: OnboardingConfig = {
  276. introduction: () => getCrashReportModalIntroduction(),
  277. install: (params: Params) => getCrashReportJavaScriptInstallStep(params),
  278. configure: () => [
  279. {
  280. type: StepType.CONFIGURE,
  281. description: getCrashReportModalConfigDescription({
  282. link: 'https://docs.sentry.io/platforms/javascript/guides/react/user-feedback/configuration/#crash-report-modal',
  283. }),
  284. additionalInfo: widgetCallout({
  285. link: 'https://docs.sentry.io/platforms/javascript/guides/react/user-feedback/#user-feedback-widget',
  286. }),
  287. },
  288. ],
  289. verify: () => [],
  290. nextSteps: () => [],
  291. };
  292. const performanceOnboarding: OnboardingConfig = {
  293. introduction: () =>
  294. t(
  295. "Adding Performance to your React project is simple. Make sure you've got these basics down."
  296. ),
  297. install: onboarding.install,
  298. configure: params => [
  299. {
  300. type: StepType.CONFIGURE,
  301. description: t(
  302. "Configuration should happen as early as possible in your application's lifecycle."
  303. ),
  304. configurations: [
  305. {
  306. language: 'javascript',
  307. code: `
  308. import React from "react";
  309. import ReactDOM from "react-dom";
  310. import * as Sentry from "@sentry/react";
  311. import App from "./App";
  312. Sentry.init({
  313. dsn: "${params.dsn.public}",
  314. integrations: [Sentry.browserTracingIntegration()],
  315. // Set tracesSampleRate to 1.0 to capture 100%
  316. // of transactions for performance monitoring.
  317. // We recommend adjusting this value in production
  318. tracesSampleRate: 1.0,
  319. // Set \`tracePropagationTargets\` to control for which URLs distributed tracing should be enabled
  320. tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
  321. });
  322. ReactDOM.render(<App />, document.getElementById("root"));
  323. // Can also use with React Concurrent Mode
  324. // ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  325. `,
  326. additionalInfo: tct(
  327. 'We recommend adjusting the value of [code:tracesSampleRate] in production. Learn more about tracing [linkTracingOptions:options], how to use the [linkTracesSampler:traces_sampler] function, or how to [linkSampleTransactions:sample transactions].',
  328. {
  329. code: <code />,
  330. linkTracingOptions: (
  331. <ExternalLink href="https://docs.sentry.io/platforms/javascript/guides/react/configuration/options/#tracing-options" />
  332. ),
  333. linkTracesSampler: (
  334. <ExternalLink href="https://docs.sentry.io/platforms/javascript/guides/react/configuration/sampling/" />
  335. ),
  336. linkSampleTransactions: (
  337. <ExternalLink href="https://docs.sentry.io/platforms/javascript/guides/react/configuration/sampling/" />
  338. ),
  339. }
  340. ),
  341. },
  342. ],
  343. },
  344. ],
  345. verify: () => [
  346. {
  347. type: StepType.VERIFY,
  348. description: tct(
  349. 'Verify that performance monitoring is working correctly with our [link:automatic instrumentation] by simply using your React application.',
  350. {
  351. link: (
  352. <ExternalLink href="https://docs.sentry.io/platforms/javascript/guides/react/tracing/instrumentation/automatic-instrumentation/" />
  353. ),
  354. }
  355. ),
  356. configurations: [
  357. {
  358. description: tct(
  359. 'You have the option to manually construct a transaction using [link:custom instrumentation].',
  360. {
  361. link: (
  362. <ExternalLink href="https://docs.sentry.io/platforms/javascript/guides/react/tracing/instrumentation/custom-instrumentation/" />
  363. ),
  364. }
  365. ),
  366. language: 'javascript',
  367. code: `
  368. const transaction = Sentry.startTransaction({ name: "test-transaction" });
  369. const span = transaction.startChild({ op: "functionX" }); // This function returns a Span
  370. // exampleFunctionCall();
  371. span.finish(); // Remember that only finished spans will be sent with the transaction
  372. transaction.finish(); // Finishing the transaction will send it to Sentry`,
  373. },
  374. {
  375. description: tct(
  376. 'In addition, [code:@sentry/react] exports a [code:withProfiler] higher order component that can be used to capture React-related spans for specific React components:',
  377. {code: <code />}
  378. ),
  379. language: 'javascript',
  380. code: `
  381. import * as Sentry from "@sentry/react";
  382. function App(props) {
  383. return <div />;
  384. }
  385. export default Sentry.withProfiler(App);
  386. `,
  387. additionalInfo: tct(
  388. 'Learn more about the profiler in [link:React Component Tracking].',
  389. {
  390. link: (
  391. <ExternalLink href="https://docs.sentry.io/platforms/javascript/guides/react/features/component-tracking/" />
  392. ),
  393. }
  394. ),
  395. },
  396. ],
  397. },
  398. ],
  399. nextSteps: () => [],
  400. };
  401. const profilingOnboarding: OnboardingConfig = {
  402. ...onboarding,
  403. introduction: params => <MaybeBrowserProfilingBetaWarning {...params} />,
  404. };
  405. const docs: Docs = {
  406. onboarding,
  407. feedbackOnboardingNpm: feedbackOnboarding,
  408. replayOnboarding,
  409. customMetricsOnboarding: getJSMetricsOnboarding({getInstallConfig}),
  410. performanceOnboarding,
  411. crashReportOnboarding,
  412. profilingOnboarding,
  413. };
  414. export default docs;