remix.tsx 9.2 KB

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