solid.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. import {Fragment} from 'react';
  2. import {buildSdkConfig} from 'sentry/components/onboarding/gettingStartedDoc/buildSdkConfig';
  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 {
  21. getProfilingDocumentHeaderConfigurationStep,
  22. MaybeBrowserProfilingBetaWarning,
  23. } from 'sentry/components/onboarding/gettingStartedDoc/utils/profilingOnboarding';
  24. import {
  25. getReplayConfigOptions,
  26. getReplayConfigureDescription,
  27. getReplayVerifyStep,
  28. } from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
  29. import {featureFlagOnboarding} from 'sentry/gettingStartedDocs/javascript/javascript';
  30. import {t, tct} from 'sentry/locale';
  31. type Params = DocsParams;
  32. const getIntegrations = (params: Params): string[] => {
  33. const integrations = [];
  34. if (params.isPerformanceSelected) {
  35. integrations.push(`Sentry.browserTracingIntegration()`);
  36. }
  37. if (params.isProfilingSelected) {
  38. integrations.push(`Sentry.browserProfilingIntegration()`);
  39. }
  40. if (params.isReplaySelected) {
  41. integrations.push(
  42. `Sentry.replayIntegration(${getReplayConfigOptions(params.replayOptions)})`
  43. );
  44. }
  45. if (params.isFeedbackSelected) {
  46. integrations.push(
  47. `
  48. Sentry.feedbackIntegration({
  49. // Additional SDK configuration goes in here, for example:
  50. colorScheme: "system",
  51. ${getFeedbackConfigOptions(params.feedbackOptions)}
  52. })`
  53. );
  54. }
  55. return integrations;
  56. };
  57. const getDynamicParts = (params: Params): string[] => {
  58. const dynamicParts: string[] = [];
  59. if (params.isPerformanceSelected) {
  60. dynamicParts.push(`
  61. // Tracing
  62. tracesSampleRate: 1.0, // Capture 100% of the transactions
  63. // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
  64. tracePropagationTargets: ["localhost", /^https:\\/\\/yourserver\\.io\\/api/]`);
  65. }
  66. if (params.isReplaySelected) {
  67. dynamicParts.push(`
  68. // Session Replay
  69. 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.
  70. replaysOnErrorSampleRate: 1.0 // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.`);
  71. }
  72. if (params.isProfilingSelected) {
  73. dynamicParts.push(`
  74. // Set profilesSampleRate to 1.0 to profile every transaction.
  75. // Since profilesSampleRate is relative to tracesSampleRate,
  76. // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate
  77. // For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would
  78. // results in 25% of transactions being profiled (0.5*0.5=0.25)
  79. profilesSampleRate: 1.0`);
  80. }
  81. return dynamicParts;
  82. };
  83. const getSdkSetupSnippet = (params: Params) => {
  84. const config = buildSdkConfig({
  85. params,
  86. staticParts: [`dsn: "${params.dsn.public}"`],
  87. getIntegrations,
  88. getDynamicParts,
  89. });
  90. return `
  91. import * as Sentry from "@sentry/solid";
  92. import { render } from "solid-js/web";
  93. import App from "./app";
  94. Sentry.init({
  95. ${config}
  96. });
  97. const root = document.getElementById("root");
  98. if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
  99. throw new Error(
  100. "Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?"
  101. );
  102. }
  103. render(() => <App />, root);
  104. `;
  105. };
  106. const getVerifySnippet = () => `
  107. <button
  108. type="button"
  109. onClick={() => {
  110. throw new Error("Sentry Frontend Error");
  111. }}
  112. >
  113. Throw error
  114. </button>`;
  115. const getInstallConfig = () => [
  116. {
  117. language: 'bash',
  118. code: [
  119. {
  120. label: 'npm',
  121. value: 'npm',
  122. language: 'bash',
  123. code: 'npm install --save @sentry/solid',
  124. },
  125. {
  126. label: 'yarn',
  127. value: 'yarn',
  128. language: 'bash',
  129. code: 'yarn add @sentry/solid',
  130. },
  131. ],
  132. },
  133. ];
  134. const onboarding: OnboardingConfig = {
  135. introduction: params => (
  136. <Fragment>
  137. <MaybeBrowserProfilingBetaWarning {...params} />
  138. <p>
  139. {tct('In this quick guide you’ll use [strong:npm] or [strong:yarn] to set up:', {
  140. strong: <strong />,
  141. })}
  142. </p>
  143. </Fragment>
  144. ),
  145. install: () => [
  146. {
  147. type: StepType.INSTALL,
  148. description: tct(
  149. 'Add the Sentry SDK as a dependency using [code:npm] or [code:yarn]:',
  150. {
  151. code: <code />,
  152. }
  153. ),
  154. configurations: getInstallConfig(),
  155. },
  156. ],
  157. configure: (params: Params) => [
  158. {
  159. type: StepType.CONFIGURE,
  160. description: tct(
  161. "Initialize Sentry as early as possible in your application's lifecycle, usually your solid app's entry point ([code:main.ts/js]):",
  162. {code: <code />}
  163. ),
  164. configurations: [
  165. {
  166. code: [
  167. {
  168. label: 'JavaScript',
  169. value: 'javascript',
  170. language: 'javascript',
  171. code: getSdkSetupSnippet(params),
  172. },
  173. ],
  174. },
  175. ...(params.isProfilingSelected
  176. ? [getProfilingDocumentHeaderConfigurationStep()]
  177. : []),
  178. ],
  179. },
  180. getUploadSourceMapsStep({
  181. guideLink: 'https://docs.sentry.io/platforms/javascript/guides/solid/sourcemaps/',
  182. ...params,
  183. }),
  184. ],
  185. verify: () => [
  186. {
  187. type: StepType.VERIFY,
  188. description: t(
  189. "This snippet contains an intentional error and can be used as a test to make sure that everything's working as expected."
  190. ),
  191. configurations: [
  192. {
  193. code: [
  194. {
  195. label: 'JavaScript',
  196. value: 'javascript',
  197. language: 'javascript',
  198. code: getVerifySnippet(),
  199. },
  200. ],
  201. },
  202. ],
  203. },
  204. ],
  205. nextSteps: () => [
  206. {
  207. id: 'solid-features',
  208. name: t('Solid Features'),
  209. description: t('Learn about our first class integration with the Solid framework.'),
  210. link: 'https://docs.sentry.io/platforms/javascript/guides/solid/features/',
  211. },
  212. ],
  213. };
  214. const replayOnboarding: OnboardingConfig = {
  215. install: () => [
  216. {
  217. type: StepType.INSTALL,
  218. description: tct(
  219. 'You need a minimum version 8.9.1 of [code:@sentry/solid] in order to use Session Replay. You do not need to install any additional packages.',
  220. {
  221. code: <code />,
  222. }
  223. ),
  224. configurations: getInstallConfig(),
  225. },
  226. ],
  227. configure: (params: Params) => [
  228. {
  229. type: StepType.CONFIGURE,
  230. description: getReplayConfigureDescription({
  231. link: 'https://docs.sentry.io/platforms/javascript/guides/solid/session-replay/',
  232. }),
  233. configurations: [
  234. {
  235. code: [
  236. {
  237. label: 'JavaScript',
  238. value: 'javascript',
  239. language: 'javascript',
  240. code: getSdkSetupSnippet(params),
  241. },
  242. ],
  243. additionalInfo: <TracePropagationMessage />,
  244. },
  245. ],
  246. },
  247. ],
  248. verify: getReplayVerifyStep(),
  249. nextSteps: () => [],
  250. };
  251. const feedbackOnboarding: OnboardingConfig = {
  252. install: () => [
  253. {
  254. type: StepType.INSTALL,
  255. description: tct(
  256. 'For the User Feedback integration to work, you must have the Sentry browser SDK package, or an equivalent framework SDK (e.g. [code:@sentry/solid]) installed, minimum version 7.85.0.',
  257. {
  258. code: <code />,
  259. }
  260. ),
  261. configurations: getInstallConfig(),
  262. },
  263. ],
  264. configure: (params: Params) => [
  265. {
  266. type: StepType.CONFIGURE,
  267. description: getFeedbackConfigureDescription({
  268. linkConfig:
  269. 'https://docs.sentry.io/platforms/javascript/guides/solid/user-feedback/configuration/',
  270. linkButton:
  271. 'https://docs.sentry.io/platforms/javascript/guides/solid/user-feedback/configuration/#bring-your-own-button',
  272. }),
  273. configurations: [
  274. {
  275. code: [
  276. {
  277. label: 'JavaScript',
  278. value: 'javascript',
  279. language: 'javascript',
  280. code: getSdkSetupSnippet(params),
  281. },
  282. ],
  283. },
  284. ],
  285. additionalInfo: crashReportCallout({
  286. link: 'https://docs.sentry.io/platforms/javascript/guides/solid/user-feedback/#crash-report-modal',
  287. }),
  288. },
  289. ],
  290. verify: () => [],
  291. nextSteps: () => [],
  292. };
  293. const crashReportOnboarding: OnboardingConfig = {
  294. introduction: () => getCrashReportModalIntroduction(),
  295. install: (params: Params) => getCrashReportJavaScriptInstallStep(params),
  296. configure: () => [
  297. {
  298. type: StepType.CONFIGURE,
  299. description: getCrashReportModalConfigDescription({
  300. link: 'https://docs.sentry.io/platforms/javascript/guides/solid/user-feedback/configuration/#crash-report-modal',
  301. }),
  302. additionalInfo: widgetCallout({
  303. link: 'https://docs.sentry.io/platforms/javascript/guides/solid/user-feedback/#user-feedback-widget',
  304. }),
  305. },
  306. ],
  307. verify: () => [],
  308. nextSteps: () => [],
  309. };
  310. const profilingOnboarding: OnboardingConfig = {
  311. ...onboarding,
  312. introduction: params => <MaybeBrowserProfilingBetaWarning {...params} />,
  313. };
  314. const docs: Docs = {
  315. onboarding,
  316. feedbackOnboardingNpm: feedbackOnboarding,
  317. replayOnboarding,
  318. crashReportOnboarding,
  319. profilingOnboarding,
  320. featureFlagOnboarding,
  321. };
  322. export default docs;