remix.tsx 9.0 KB

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