remix.tsx 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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 {
  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: params => [
  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. description: <CopyDsnField params={params} />,
  123. },
  124. ],
  125. },
  126. ],
  127. verify: () => [
  128. {
  129. type: StepType.VERIFY,
  130. description: (
  131. <Fragment>
  132. <p>
  133. {tct(
  134. 'Start your development server and visit [code:/sentry-example-page] if you have set it up. Click the button to trigger a test error.',
  135. {
  136. code: <code />,
  137. }
  138. )}
  139. </p>
  140. <p>
  141. {t(
  142. 'Or, trigger a sample error by calling a function that does not exist somewhere in your application.'
  143. )}
  144. </p>
  145. </Fragment>
  146. ),
  147. configurations: [
  148. {
  149. code: [
  150. {
  151. label: 'Javascript',
  152. value: 'javascript',
  153. language: 'javascript',
  154. code: `myUndefinedFunction();`,
  155. },
  156. ],
  157. },
  158. ],
  159. additionalInfo: t(
  160. 'If you see an issue in your Sentry dashboard, you have successfully set up Sentry.'
  161. ),
  162. },
  163. ],
  164. nextSteps: () => [],
  165. };
  166. const replayOnboarding: OnboardingConfig = {
  167. install: (params: Params) => getInstallConfig(params),
  168. configure: (params: Params) => [
  169. {
  170. type: StepType.CONFIGURE,
  171. description: getReplayConfigureDescription({
  172. link: 'https://docs.sentry.io/platforms/javascript/guides/remix/session-replay/',
  173. }),
  174. configurations: [
  175. {
  176. code: [
  177. {
  178. label: 'entry.client.tsx',
  179. value: 'javascript',
  180. language: 'javascript',
  181. code: getReplaySDKSetupSnippet({
  182. importStatement: `import * as Sentry from "@sentry/remix";`,
  183. dsn: params.dsn.public,
  184. mask: params.replayOptions?.mask,
  185. block: params.replayOptions?.block,
  186. }),
  187. },
  188. ],
  189. },
  190. ],
  191. additionalInfo: (
  192. <Fragment>
  193. <TracePropagationMessage />
  194. {tct(
  195. '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].',
  196. {code: <code />}
  197. )}
  198. </Fragment>
  199. ),
  200. },
  201. ],
  202. verify: getReplayVerifyStep(),
  203. nextSteps: () => [],
  204. };
  205. const feedbackOnboarding: OnboardingConfig = {
  206. install: (params: Params) => [
  207. {
  208. type: StepType.INSTALL,
  209. description: tct(
  210. '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.',
  211. {
  212. code: <code />,
  213. }
  214. ),
  215. configurations: getConfigStep(params),
  216. },
  217. ],
  218. configure: (params: Params) => [
  219. {
  220. type: StepType.CONFIGURE,
  221. description: getFeedbackConfigureDescription({
  222. linkConfig:
  223. 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/configuration/',
  224. linkButton:
  225. 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/configuration/#bring-your-own-button',
  226. }),
  227. configurations: [
  228. {
  229. code: [
  230. {
  231. label: 'entry.client.tsx',
  232. value: 'javascript',
  233. language: 'javascript',
  234. code: getFeedbackSDKSetupSnippet({
  235. importStatement: `import * as Sentry from "@sentry/remix";`,
  236. dsn: params.dsn.public,
  237. feedbackOptions: params.feedbackOptions,
  238. }),
  239. },
  240. ],
  241. },
  242. ],
  243. additionalInfo: (
  244. <Fragment>
  245. <p>
  246. {tct(
  247. 'Note: The Feedback integration only needs to be added to your [code:entry.client.tsx] file.',
  248. {code: <code />}
  249. )}
  250. </p>
  251. {crashReportCallout({
  252. link: 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/#user-feedback-api',
  253. })}
  254. </Fragment>
  255. ),
  256. },
  257. ],
  258. verify: () => [],
  259. nextSteps: () => [],
  260. };
  261. const crashReportOnboarding: OnboardingConfig = {
  262. introduction: () => getCrashReportModalIntroduction(),
  263. install: (params: Params) => getCrashReportJavaScriptInstallStep(params),
  264. configure: () => [
  265. {
  266. type: StepType.CONFIGURE,
  267. description: getCrashReportModalConfigDescription({
  268. link: 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/configuration/#crash-report-modal',
  269. }),
  270. additionalInfo: widgetCallout({
  271. link: 'https://docs.sentry.io/platforms/javascript/guides/remix/user-feedback/#user-feedback-widget',
  272. }),
  273. },
  274. ],
  275. verify: () => [],
  276. nextSteps: () => [],
  277. };
  278. const docs: Docs = {
  279. onboarding,
  280. feedbackOnboardingNpm: feedbackOnboarding,
  281. replayOnboarding,
  282. crashReportOnboarding,
  283. featureFlagOnboarding,
  284. };
  285. export default docs;