remix.tsx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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 {CopyDsnField} from 'sentry/components/onboarding/gettingStartedDoc/copyDsnField';
  6. import crashReportCallout from 'sentry/components/onboarding/gettingStartedDoc/feedback/crashReportCallout';
  7. import widgetCallout from 'sentry/components/onboarding/gettingStartedDoc/feedback/widgetCallout';
  8. import TracePropagationMessage from 'sentry/components/onboarding/gettingStartedDoc/replay/tracePropagationMessage';
  9. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  10. import type {
  11. Docs,
  12. DocsParams,
  13. OnboardingConfig,
  14. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  15. import {
  16. getCrashReportJavaScriptInstallStep,
  17. getCrashReportModalConfigDescription,
  18. getCrashReportModalIntroduction,
  19. getFeedbackConfigureDescription,
  20. getFeedbackSDKSetupSnippet,
  21. } from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding';
  22. import {getJSMetricsOnboarding} from 'sentry/components/onboarding/gettingStartedDoc/utils/metricsOnboarding';
  23. import {
  24. getReplayConfigureDescription,
  25. getReplaySDKSetupSnippet,
  26. getReplayVerifyStep,
  27. } from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
  28. import {featureFlagOnboarding} from 'sentry/gettingStartedDocs/javascript/javascript';
  29. import {t, tct} from 'sentry/locale';
  30. type Params = DocsParams;
  31. const getConfigStep = ({isSelfHosted, organization, projectSlug}: Params) => {
  32. const urlParam = isSelfHosted ? '' : '--saas';
  33. return [
  34. {
  35. description: tct(
  36. 'Configure your app automatically by running the [wizardLink:Sentry wizard] in the root of your project.',
  37. {
  38. wizardLink: (
  39. <ExternalLink href="https://docs.sentry.io/platforms/javascript/guides/remix/#install" />
  40. ),
  41. }
  42. ),
  43. language: 'bash',
  44. code: `npx @sentry/wizard@latest -i remix ${urlParam} --org ${organization.slug} --project ${projectSlug}`,
  45. },
  46. ];
  47. };
  48. const getInstallConfig = (params: Params) => [
  49. {
  50. type: StepType.INSTALL,
  51. configurations: getConfigStep(params),
  52. },
  53. ];
  54. const onboarding: OnboardingConfig = {
  55. introduction: () => (
  56. <p>
  57. {tct(
  58. "Sentry's integration with [remixLink:Remix] supports Remix 1.0.0 and above.",
  59. {
  60. remixLink: <ExternalLink href="https://remix.run/" />,
  61. }
  62. )}
  63. </p>
  64. ),
  65. install: (params: Params) => [
  66. {
  67. title: t('Automatic Configuration (Recommended)'),
  68. configurations: getConfigStep(params),
  69. },
  70. ],
  71. configure: params => [
  72. {
  73. collapsible: true,
  74. title: t('Manual Configuration'),
  75. description: tct(
  76. 'Alternatively, you can also [manualSetupLink:set up the SDK manually], by following these steps:',
  77. {
  78. manualSetupLink: (
  79. <ExternalLink href="https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/" />
  80. ),
  81. }
  82. ),
  83. configurations: [
  84. {
  85. description: (
  86. <List symbol="bullet">
  87. <ListItem>
  88. {tct(
  89. "Create two files in the root directory of your project, [code:entry.client.tsx] and [code:entry.server.tsx] (if they don't already exist).",
  90. {
  91. code: <code />,
  92. }
  93. )}
  94. </ListItem>
  95. <ListItem>
  96. {tct(
  97. 'Add the default [sentryInitCode:Sentry.init] call to both, client and server entry files.',
  98. {
  99. sentryInitCode: <code />,
  100. }
  101. )}
  102. </ListItem>
  103. <ListItem>
  104. {tct(
  105. 'Create a [code:.sentryclirc] with an auth token to upload source maps (this file is automatically added to your [code:.gitignore]).',
  106. {
  107. code: <code />,
  108. }
  109. )}
  110. </ListItem>
  111. <ListItem>
  112. {tct(
  113. 'Adjust your [code:build] script in your [code:package.json] to automatically upload source maps to Sentry when you build your application.',
  114. {
  115. code: <code />,
  116. }
  117. )}
  118. </ListItem>
  119. </List>
  120. ),
  121. },
  122. {
  123. description: <CopyDsnField params={params} />,
  124. },
  125. ],
  126. },
  127. ],
  128. verify: () => [
  129. {
  130. type: StepType.VERIFY,
  131. description: (
  132. <Fragment>
  133. <p>
  134. {tct(
  135. 'Start your development server and visit [code:/sentry-example-page] if you have set it up. Click the button to trigger a test error.',
  136. {
  137. code: <code />,
  138. }
  139. )}
  140. </p>
  141. <p>
  142. {t(
  143. 'Or, trigger a sample error by calling a function that does not exist somewhere in your application.'
  144. )}
  145. </p>
  146. </Fragment>
  147. ),
  148. configurations: [
  149. {
  150. code: [
  151. {
  152. label: 'Javascript',
  153. value: 'javascript',
  154. language: 'javascript',
  155. code: `myUndefinedFunction();`,
  156. },
  157. ],
  158. },
  159. ],
  160. additionalInfo: t(
  161. 'If you see an issue in your Sentry dashboard, you have successfully set up Sentry.'
  162. ),
  163. },
  164. ],
  165. nextSteps: () => [],
  166. };
  167. const replayOnboarding: OnboardingConfig = {
  168. install: (params: Params) => getInstallConfig(params),
  169. configure: (params: Params) => [
  170. {
  171. type: StepType.CONFIGURE,
  172. description: getReplayConfigureDescription({
  173. link: 'https://docs.sentry.io/platforms/javascript/guides/remix/session-replay/',
  174. }),
  175. configurations: [
  176. {
  177. code: [
  178. {
  179. label: 'entry.client.tsx',
  180. value: 'javascript',
  181. language: 'javascript',
  182. code: getReplaySDKSetupSnippet({
  183. importStatement: `import * as Sentry from "@sentry/remix";`,
  184. dsn: params.dsn.public,
  185. mask: params.replayOptions?.mask,
  186. block: params.replayOptions?.block,
  187. }),
  188. },
  189. ],
  190. },
  191. ],
  192. additionalInfo: (
  193. <Fragment>
  194. <TracePropagationMessage />
  195. {tct(
  196. 'Note: The Replay integration only needs to be added to your [code:entry.client.tsx] file. It will not run if it is added into [code:sentry.server.config.js].',
  197. {code: <code />}
  198. )}
  199. </Fragment>
  200. ),
  201. },
  202. ],
  203. verify: getReplayVerifyStep(),
  204. nextSteps: () => [],
  205. };
  206. const feedbackOnboarding: OnboardingConfig = {
  207. install: (params: Params) => [
  208. {
  209. type: StepType.INSTALL,
  210. description: tct(
  211. 'For the User Feedback integration to work, you must have the Sentry browser SDK package, or an equivalent framework SDK (e.g. [code:@sentry/remix]) installed, minimum version 7.85.0.',
  212. {
  213. code: <code />,
  214. }
  215. ),
  216. configurations: getConfigStep(params),
  217. },
  218. ],
  219. configure: (params: Params) => [
  220. {
  221. type: StepType.CONFIGURE,
  222. description: getFeedbackConfigureDescription({
  223. linkConfig:
  224. 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/configuration/',
  225. linkButton:
  226. 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/configuration/#bring-your-own-button',
  227. }),
  228. configurations: [
  229. {
  230. code: [
  231. {
  232. label: 'entry.client.tsx',
  233. value: 'javascript',
  234. language: 'javascript',
  235. code: getFeedbackSDKSetupSnippet({
  236. importStatement: `import * as Sentry from "@sentry/remix";`,
  237. dsn: params.dsn.public,
  238. feedbackOptions: params.feedbackOptions,
  239. }),
  240. },
  241. ],
  242. },
  243. ],
  244. additionalInfo: (
  245. <Fragment>
  246. <p>
  247. {tct(
  248. 'Note: The Feedback integration only needs to be added to your [code:entry.client.tsx] file.',
  249. {code: <code />}
  250. )}
  251. </p>
  252. {crashReportCallout({
  253. link: 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/#user-feedback-api',
  254. })}
  255. </Fragment>
  256. ),
  257. },
  258. ],
  259. verify: () => [],
  260. nextSteps: () => [],
  261. };
  262. const crashReportOnboarding: OnboardingConfig = {
  263. introduction: () => getCrashReportModalIntroduction(),
  264. install: (params: Params) => getCrashReportJavaScriptInstallStep(params),
  265. configure: () => [
  266. {
  267. type: StepType.CONFIGURE,
  268. description: getCrashReportModalConfigDescription({
  269. link: 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/configuration/#crash-report-modal',
  270. }),
  271. additionalInfo: widgetCallout({
  272. link: 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/#user-feedback-widget',
  273. }),
  274. },
  275. ],
  276. verify: () => [],
  277. nextSteps: () => [],
  278. };
  279. const docs: Docs = {
  280. onboarding,
  281. feedbackOnboardingNpm: feedbackOnboarding,
  282. replayOnboarding,
  283. customMetricsOnboarding: getJSMetricsOnboarding({getInstallConfig}),
  284. crashReportOnboarding,
  285. featureFlagOnboarding,
  286. };
  287. export default docs;