javascript.tsx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. import {css} from '@emotion/react';
  2. import {SdkProviderEnum as FeatureFlagProviderEnum} from 'sentry/components/events/featureFlags/utils';
  3. import ExternalLink from 'sentry/components/links/externalLink';
  4. import crashReportCallout from 'sentry/components/onboarding/gettingStartedDoc/feedback/crashReportCallout';
  5. import widgetCallout from 'sentry/components/onboarding/gettingStartedDoc/feedback/widgetCallout';
  6. import TracePropagationMessage from 'sentry/components/onboarding/gettingStartedDoc/replay/tracePropagationMessage';
  7. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  8. import type {
  9. BasePlatformOptions,
  10. Docs,
  11. DocsParams,
  12. OnboardingConfig,
  13. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  14. import {getUploadSourceMapsStep} from 'sentry/components/onboarding/gettingStartedDoc/utils';
  15. import {
  16. getCrashReportJavaScriptInstallStep,
  17. getCrashReportModalConfigDescription,
  18. getCrashReportModalIntroduction,
  19. getFeedbackConfigOptions,
  20. getFeedbackConfigureDescription,
  21. } from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding';
  22. import {
  23. getProfilingDocumentHeaderConfigurationStep,
  24. MaybeBrowserProfilingBetaWarning,
  25. } from 'sentry/components/onboarding/gettingStartedDoc/utils/profilingOnboarding';
  26. import {
  27. getReplayConfigOptions,
  28. getReplayConfigureDescription,
  29. getReplayVerifyStep,
  30. } from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
  31. import {
  32. feedbackOnboardingJsLoader,
  33. replayOnboardingJsLoader,
  34. } from 'sentry/gettingStartedDocs/javascript/jsLoader/jsLoader';
  35. import {t, tct} from 'sentry/locale';
  36. import {space} from 'sentry/styles/space';
  37. import {trackAnalytics} from 'sentry/utils/analytics';
  38. import TextBlock from 'sentry/views/settings/components/text/textBlock';
  39. import {updateDynamicSdkLoaderOptions} from './jsLoader/updateDynamicSdkLoaderOptions';
  40. export enum InstallationMode {
  41. AUTO = 'auto',
  42. MANUAL = 'manual',
  43. }
  44. const platformOptions = {
  45. installationMode: {
  46. label: t('Installation Mode'),
  47. items: [
  48. {
  49. label: t('Loader Script'),
  50. value: InstallationMode.AUTO,
  51. },
  52. {
  53. label: t('Npm/Yarn'),
  54. value: InstallationMode.MANUAL,
  55. },
  56. ],
  57. defaultValue: InstallationMode.AUTO,
  58. },
  59. } satisfies BasePlatformOptions;
  60. type PlatformOptions = typeof platformOptions;
  61. type Params = DocsParams<PlatformOptions>;
  62. type FeatureFlagConfiguration = {
  63. integrationName: string;
  64. makeConfigureCode: (dsn: string) => string;
  65. makeVerifyCode: () => string;
  66. packageName: string;
  67. };
  68. const FEATURE_FLAG_CONFIGURATION_MAP: Record<
  69. FeatureFlagProviderEnum,
  70. FeatureFlagConfiguration
  71. > = {
  72. [FeatureFlagProviderEnum.GENERIC]: {
  73. integrationName: `featureFlagsIntegration`,
  74. packageName: '',
  75. makeConfigureCode: (dsn: string) => `import * as Sentry from "@sentry/browser";
  76. Sentry.init({
  77. dsn: "${dsn}",
  78. integrations: [Sentry.featureFlagsIntegration()],
  79. });`,
  80. makeVerifyCode:
  81. () => `const flagsIntegration = Sentry.getClient()?.getIntegrationByName<Sentry.FeatureFlagsIntegration>("FeatureFlags");
  82. if (flagsIntegration) {
  83. flagsIntegration.addFeatureFlag("test-flag", false);
  84. } else {
  85. // Something went wrong, check your DSN and/or integrations
  86. }
  87. Sentry.captureException(new Error("Something went wrong!"));`,
  88. },
  89. [FeatureFlagProviderEnum.LAUNCHDARKLY]: {
  90. integrationName: `launchDarklyIntegration`,
  91. packageName: 'launchdarkly-js-client-sdk',
  92. makeConfigureCode: (dsn: string) => `import * as Sentry from "@sentry/browser";
  93. import * as LaunchDarkly from "launchdarkly-js-client-sdk";
  94. Sentry.init({
  95. dsn: "${dsn}",
  96. integrations: [Sentry.launchDarklyIntegration()],
  97. });
  98. const ldClient = LaunchDarkly.initialize(
  99. "my-client-ID",
  100. { kind: "user", key: "my-user-context-key" },
  101. { inspectors: [Sentry.buildLaunchDarklyFlagUsedHandler()] },
  102. );`,
  103. makeVerifyCode: () => `// You may have to wait for your client to initialize first.
  104. ldClient?.variation("test-flag", false);
  105. Sentry.captureException(new Error("Something went wrong!"));`,
  106. },
  107. [FeatureFlagProviderEnum.OPENFEATURE]: {
  108. integrationName: `openFeatureIntegration`,
  109. packageName: '@openfeature/web-sdk',
  110. makeConfigureCode: (dsn: string) => `import * as Sentry from "@sentry/browser";
  111. import { OpenFeature } from "@openfeature/web-sdk";
  112. Sentry.init({
  113. dsn: "${dsn}",
  114. integrations: [Sentry.openFeatureIntegration()],
  115. });
  116. OpenFeature.setProvider(new MyProviderOfChoice());
  117. OpenFeature.addHooks(new Sentry.OpenFeatureIntegrationHook());`,
  118. makeVerifyCode: () => `const client = OpenFeature.getClient();
  119. const result = client.getBooleanValue("test-flag", false);
  120. Sentry.captureException(new Error("Something went wrong!"));`,
  121. },
  122. [FeatureFlagProviderEnum.STATSIG]: {
  123. integrationName: `statsigIntegration`,
  124. packageName: '@statsig/js-client',
  125. makeConfigureCode: (dsn: string) => `import * as Sentry from "@sentry/browser";
  126. import { StatsigClient } from "@statsig/js-client";
  127. const statsigClient = new StatsigClient(
  128. YOUR_SDK_KEY,
  129. { userID: "my-user-id" },
  130. {},
  131. ); // see Statsig SDK reference.
  132. Sentry.init({
  133. dsn: "${dsn}",
  134. integrations: [
  135. Sentry.statsigIntegration({ featureFlagClient: statsigClient }),
  136. ],
  137. });`,
  138. makeVerifyCode:
  139. () => `await statsigClient.initializeAsync(); // or statsigClient.initializeSync();
  140. const result = statsigClient.checkGate("my-feature-gate");
  141. Sentry.captureException(new Error("something went wrong"));`,
  142. },
  143. [FeatureFlagProviderEnum.UNLEASH]: {
  144. integrationName: `unleashIntegration`,
  145. packageName: 'unleash-proxy-client',
  146. makeConfigureCode: (dsn: string) => `import * as Sentry from "@sentry/browser";
  147. import { UnleashClient } from "unleash-proxy-client";
  148. Sentry.init({
  149. dsn: "${dsn}",
  150. integrations: [
  151. Sentry.unleashIntegration({ featureFlagClientClass: UnleashClient }),
  152. ],
  153. });
  154. const unleash = new UnleashClient({
  155. url: "https://<your-unleash-instance>/api/frontend",
  156. clientKey: "<your-client-side-token>",
  157. appName: "my-webapp",
  158. });
  159. unleash.start();`,
  160. makeVerifyCode: () => `// You may have to wait for your client to synchronize first.
  161. unleash.isEnabled("test-flag");
  162. Sentry.captureException(new Error("Something went wrong!"));`,
  163. },
  164. };
  165. const isAutoInstall = (params: Params) =>
  166. params.platformOptions.installationMode === InstallationMode.AUTO;
  167. const getSdkSetupSnippet = (params: Params) => `
  168. import * as Sentry from "@sentry/browser";
  169. Sentry.init({
  170. dsn: "${params.dsn.public}",
  171. integrations: [${
  172. params.isPerformanceSelected
  173. ? `
  174. Sentry.browserTracingIntegration(),`
  175. : ''
  176. }${
  177. params.isProfilingSelected
  178. ? `
  179. Sentry.browserProfilingIntegration(),`
  180. : ''
  181. }${
  182. params.isFeedbackSelected
  183. ? `
  184. Sentry.feedbackIntegration({
  185. // Additional SDK configuration goes in here, for example:
  186. colorScheme: "system",
  187. ${getFeedbackConfigOptions(params.feedbackOptions)}}),`
  188. : ''
  189. }${
  190. params.isReplaySelected
  191. ? `
  192. Sentry.replayIntegration(${getReplayConfigOptions(params.replayOptions)}),`
  193. : ''
  194. }
  195. ],${
  196. params.isPerformanceSelected
  197. ? `
  198. // Tracing
  199. tracesSampleRate: 1.0, // Capture 100% of the transactions
  200. // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
  201. tracePropagationTargets: ["localhost", /^https:\\/\\/yourserver\\.io\\/api/],`
  202. : ''
  203. }${
  204. params.isReplaySelected
  205. ? `
  206. // Session Replay
  207. 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.
  208. replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.`
  209. : ''
  210. }${
  211. params.isProfilingSelected
  212. ? `
  213. // Set profilesSampleRate to 1.0 to profile every transaction.
  214. // Since profilesSampleRate is relative to tracesSampleRate,
  215. // the final profiling rate can be computed as tracesSampleRate * profilesSampleRate
  216. // For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would
  217. // results in 25% of transactions being profiled (0.5*0.5=0.25)
  218. profilesSampleRate: 1.0,`
  219. : ''
  220. }
  221. });
  222. `;
  223. const getVerifyJSSnippet = () => `
  224. myUndefinedFunction();`;
  225. const getInstallConfig = () => [
  226. {
  227. language: 'bash',
  228. code: [
  229. {
  230. label: 'npm',
  231. value: 'npm',
  232. language: 'bash',
  233. code: 'npm install --save @sentry/browser',
  234. },
  235. {
  236. label: 'yarn',
  237. value: 'yarn',
  238. language: 'bash',
  239. code: 'yarn add @sentry/browser',
  240. },
  241. ],
  242. },
  243. ];
  244. const getVerifyConfig = () => [
  245. {
  246. type: StepType.VERIFY,
  247. description: t(
  248. "This snippet contains an intentional error and can be used as a test to make sure that everything's working as expected."
  249. ),
  250. configurations: [
  251. {
  252. code: [
  253. {
  254. label: 'Javascript',
  255. value: 'javascript',
  256. language: 'javascript',
  257. code: getVerifyJSSnippet(),
  258. },
  259. ],
  260. },
  261. ],
  262. },
  263. ];
  264. const loaderScriptOnboarding: OnboardingConfig<PlatformOptions> = {
  265. introduction: () =>
  266. tct('In this quick guide you’ll use our [strong: Loader Script] to set up:', {
  267. strong: <strong />,
  268. }),
  269. install: params => [
  270. {
  271. type: StepType.INSTALL,
  272. description: t('Add this script tag to the top of the page:'),
  273. configurations: [
  274. {
  275. language: 'html',
  276. code: [
  277. {
  278. label: 'HTML',
  279. value: 'html',
  280. language: 'html',
  281. code: `
  282. <script
  283. src="${params.dsn.cdn}"
  284. crossorigin="anonymous"
  285. ></script>`,
  286. },
  287. ],
  288. },
  289. ],
  290. },
  291. ],
  292. configure: params => [
  293. {
  294. title: t('Configure SDK (Optional)'),
  295. description: t(
  296. "Initialize Sentry as early as possible in your application's lifecycle."
  297. ),
  298. collapsible: true,
  299. configurations: [
  300. {
  301. language: 'html',
  302. code: [
  303. {
  304. label: 'HTML',
  305. value: 'html',
  306. language: 'html',
  307. code: `
  308. <script>
  309. Sentry.onLoad(function() {
  310. Sentry.init({${
  311. !(params.isPerformanceSelected || params.isReplaySelected)
  312. ? `
  313. // You can add any additional configuration here`
  314. : ''
  315. }${
  316. params.isPerformanceSelected
  317. ? `
  318. // Tracing
  319. tracesSampleRate: 1.0, // Capture 100% of the transactions`
  320. : ''
  321. }${
  322. params.isReplaySelected
  323. ? `
  324. // Session Replay
  325. 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.
  326. replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.`
  327. : ''
  328. }
  329. });
  330. });
  331. </script>`,
  332. },
  333. ],
  334. },
  335. ],
  336. onOptionalToggleClick: showOptionalConfig => {
  337. if (showOptionalConfig) {
  338. trackAnalytics('onboarding.js_loader_npm_docs_optional_shown', {
  339. organization: params.organization,
  340. platform: params.platformKey,
  341. project_id: params.projectId,
  342. });
  343. }
  344. },
  345. },
  346. ],
  347. verify: getVerifyConfig,
  348. nextSteps: () => [
  349. {
  350. id: 'source-maps',
  351. name: t('Source Maps'),
  352. description: t('Learn how to enable readable stack traces in your Sentry errors.'),
  353. link: 'https://docs.sentry.io/platforms/javascript/sourcemaps/',
  354. },
  355. ],
  356. onPageLoad: params => {
  357. return () => {
  358. trackAnalytics('onboarding.setup_loader_docs_rendered', {
  359. organization: params.organization,
  360. platform: params.platformKey,
  361. project_id: params.projectId,
  362. });
  363. };
  364. },
  365. onPlatformOptionsChange: params => {
  366. return () => {
  367. trackAnalytics('onboarding.js_loader_npm_docs_shown', {
  368. organization: params.organization,
  369. platform: params.platformKey,
  370. project_id: params.projectId,
  371. });
  372. };
  373. },
  374. onProductSelectionChange: params => {
  375. return products => {
  376. updateDynamicSdkLoaderOptions({
  377. orgSlug: params.organization.slug,
  378. projectSlug: params.projectSlug,
  379. products,
  380. projectKey: params.projectKeyId,
  381. api: params.api,
  382. });
  383. };
  384. },
  385. onProductSelectionLoad: params => {
  386. return products => {
  387. updateDynamicSdkLoaderOptions({
  388. orgSlug: params.organization.slug,
  389. projectSlug: params.projectSlug,
  390. products,
  391. projectKey: params.projectKeyId,
  392. api: params.api,
  393. });
  394. };
  395. },
  396. };
  397. const packageManagerOnboarding: OnboardingConfig<PlatformOptions> = {
  398. introduction: () =>
  399. tct('In this quick guide you’ll use [strong:npm] or [strong:yarn] to set up:', {
  400. strong: <strong />,
  401. }),
  402. install: () => [
  403. {
  404. type: StepType.INSTALL,
  405. description: t(
  406. 'Sentry captures data by using an SDK within your application’s runtime.'
  407. ),
  408. configurations: getInstallConfig(),
  409. },
  410. ],
  411. configure: params => [
  412. {
  413. type: StepType.CONFIGURE,
  414. description: t(
  415. "Initialize Sentry as early as possible in your application's lifecycle."
  416. ),
  417. configurations: [
  418. {
  419. code: [
  420. {
  421. label: 'JavaScript',
  422. value: 'javascript',
  423. language: 'javascript',
  424. code: getSdkSetupSnippet(params),
  425. },
  426. ],
  427. },
  428. ...(params.isProfilingSelected
  429. ? [getProfilingDocumentHeaderConfigurationStep()]
  430. : []),
  431. ],
  432. },
  433. getUploadSourceMapsStep({
  434. guideLink: 'https://docs.sentry.io/platforms/javascript/sourcemaps/',
  435. ...params,
  436. }),
  437. ],
  438. verify: getVerifyConfig,
  439. nextSteps: () => [],
  440. onPageLoad: params => {
  441. return () => {
  442. trackAnalytics('onboarding.js_loader_npm_docs_shown', {
  443. organization: params.organization,
  444. platform: params.platformKey,
  445. project_id: params.projectId,
  446. });
  447. };
  448. },
  449. onPlatformOptionsChange: params => {
  450. return () => {
  451. trackAnalytics('onboarding.setup_loader_docs_rendered', {
  452. organization: params.organization,
  453. platform: params.platformKey,
  454. project_id: params.projectId,
  455. });
  456. };
  457. },
  458. };
  459. const onboarding: OnboardingConfig<PlatformOptions> = {
  460. introduction: params => (
  461. <div
  462. css={css`
  463. display: flex;
  464. flex-direction: column;
  465. gap: ${space(1)};
  466. `}
  467. >
  468. <MaybeBrowserProfilingBetaWarning {...params} />
  469. <TextBlock noMargin>
  470. {isAutoInstall(params)
  471. ? loaderScriptOnboarding.introduction?.(params)
  472. : packageManagerOnboarding.introduction?.(params)}
  473. </TextBlock>
  474. </div>
  475. ),
  476. install: params =>
  477. isAutoInstall(params)
  478. ? loaderScriptOnboarding.install(params)
  479. : packageManagerOnboarding.install(params),
  480. configure: (params: Params) =>
  481. isAutoInstall(params)
  482. ? loaderScriptOnboarding.configure(params)
  483. : packageManagerOnboarding.configure(params),
  484. verify: params =>
  485. isAutoInstall(params)
  486. ? loaderScriptOnboarding.verify(params)
  487. : packageManagerOnboarding.verify(params),
  488. nextSteps: params =>
  489. isAutoInstall(params)
  490. ? loaderScriptOnboarding.nextSteps?.(params)
  491. : packageManagerOnboarding.nextSteps?.(params),
  492. onPageLoad: params =>
  493. isAutoInstall(params)
  494. ? loaderScriptOnboarding.onPageLoad?.(params)
  495. : packageManagerOnboarding.onPageLoad?.(params),
  496. onProductSelectionChange: params =>
  497. isAutoInstall(params)
  498. ? loaderScriptOnboarding.onProductSelectionChange?.(params)
  499. : packageManagerOnboarding.onProductSelectionChange?.(params),
  500. onPlatformOptionsChange: params =>
  501. isAutoInstall(params)
  502. ? loaderScriptOnboarding.onPlatformOptionsChange?.(params)
  503. : packageManagerOnboarding.onPlatformOptionsChange?.(params),
  504. onProductSelectionLoad: params =>
  505. isAutoInstall(params)
  506. ? loaderScriptOnboarding.onProductSelectionLoad?.(params)
  507. : packageManagerOnboarding.onProductSelectionLoad?.(params),
  508. };
  509. const replayOnboarding: OnboardingConfig<PlatformOptions> = {
  510. install: () => [
  511. {
  512. type: StepType.INSTALL,
  513. description: tct(
  514. 'For the Session Replay to work, you must have the Sentry browser SDK package, or an equivalent framework SDK (e.g. [code:@sentry/react]) installed, minimum version 7.27.0.',
  515. {
  516. code: <code />,
  517. }
  518. ),
  519. configurations: getInstallConfig(),
  520. },
  521. ],
  522. configure: (params: Params) => [
  523. {
  524. type: StepType.CONFIGURE,
  525. description: getReplayConfigureDescription({
  526. link: 'https://docs.sentry.io/platforms/javascript/session-replay/',
  527. }),
  528. configurations: [
  529. {
  530. code: [
  531. {
  532. label: 'JavaScript',
  533. value: 'javascript',
  534. language: 'javascript',
  535. code: getSdkSetupSnippet(params),
  536. },
  537. ],
  538. },
  539. ],
  540. additionalInfo: <TracePropagationMessage />,
  541. },
  542. ],
  543. verify: getReplayVerifyStep(),
  544. nextSteps: () => [],
  545. };
  546. const feedbackOnboarding: OnboardingConfig<PlatformOptions> = {
  547. install: () => [
  548. {
  549. type: StepType.INSTALL,
  550. description: tct(
  551. 'For the User Feedback integration to work, you must have the Sentry browser SDK package, or an equivalent framework SDK (e.g. [code:@sentry/react]) installed, minimum version 7.85.0.',
  552. {
  553. code: <code />,
  554. }
  555. ),
  556. configurations: getInstallConfig(),
  557. },
  558. ],
  559. configure: (params: Params) => [
  560. {
  561. type: StepType.CONFIGURE,
  562. description: getFeedbackConfigureDescription({
  563. linkConfig:
  564. 'https://docs.sentry.io/platforms/javascript/user-feedback/configuration/',
  565. linkButton:
  566. 'https://docs.sentry.io/platforms/javascript/user-feedback/configuration/#bring-your-own-button',
  567. }),
  568. configurations: [
  569. {
  570. code: [
  571. {
  572. label: 'JavaScript',
  573. value: 'javascript',
  574. language: 'javascript',
  575. code: getSdkSetupSnippet(params),
  576. },
  577. ],
  578. },
  579. ],
  580. additionalInfo: crashReportCallout({
  581. link: 'https://docs.sentry.io/platforms/javascript/user-feedback/#crash-report-modal',
  582. }),
  583. },
  584. ],
  585. verify: () => [],
  586. nextSteps: () => [],
  587. };
  588. const crashReportOnboarding: OnboardingConfig<PlatformOptions> = {
  589. introduction: () => getCrashReportModalIntroduction(),
  590. install: (params: Params) => getCrashReportJavaScriptInstallStep(params),
  591. configure: () => [
  592. {
  593. type: StepType.CONFIGURE,
  594. description: getCrashReportModalConfigDescription({
  595. link: 'https://docs.sentry.io/platforms/javascript/user-feedback/configuration/#crash-report-modal',
  596. }),
  597. additionalInfo: widgetCallout({
  598. link: 'https://docs.sentry.io/platforms/javascript/user-feedback/#user-feedback-widget',
  599. }),
  600. },
  601. ],
  602. verify: () => [],
  603. nextSteps: () => [],
  604. };
  605. const performanceOnboarding: OnboardingConfig<PlatformOptions> = {
  606. introduction: () =>
  607. t(
  608. "Adding Performance to your Browser JavaScript project is simple. Make sure you've got these basics down."
  609. ),
  610. install: () => [
  611. {
  612. type: StepType.INSTALL,
  613. description: tct(
  614. 'Install our JavaScript browser SDK using either [code:yarn] or [code:npm]:',
  615. {code: <code />}
  616. ),
  617. configurations: getInstallConfig(),
  618. },
  619. ],
  620. configure: params => [
  621. {
  622. type: StepType.CONFIGURE,
  623. configurations: [
  624. {
  625. language: 'javascript',
  626. description: t(
  627. "Configuration should happen as early as possible in your application's lifecycle."
  628. ),
  629. code: `
  630. import * as Sentry from "@sentry/browser";
  631. Sentry.init({
  632. dsn: "${params.dsn.public}",
  633. integrations: [Sentry.browserTracingIntegration()],
  634. // Set tracesSampleRate to 1.0 to capture 100%
  635. // of transactions for performance monitoring.
  636. // We recommend adjusting this value in production
  637. tracesSampleRate: 1.0,
  638. // Set \`tracePropagationTargets\` to control for which URLs distributed tracing should be enabled
  639. tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
  640. });
  641. `,
  642. additionalInfo: tct(
  643. 'We recommend adjusting the value of [code:tracesSampleRate] in production. Learn more about tracing [linkTracingOptions:options], how to use the [linkTracesSampler:traces_sampler] function, or how to do [linkSampleTransactions:sampling].',
  644. {
  645. code: <code />,
  646. linkTracingOptions: (
  647. <ExternalLink href="https://docs.sentry.io/platforms/javascript/configuration/options/#tracing-options" />
  648. ),
  649. linkTracesSampler: (
  650. <ExternalLink href="https://docs.sentry.io/platforms/javascript/configuration/sampling/" />
  651. ),
  652. linkSampleTransactions: (
  653. <ExternalLink href="https://docs.sentry.io/platforms/javascript/configuration/sampling/" />
  654. ),
  655. }
  656. ),
  657. },
  658. {
  659. language: 'javascript',
  660. description: tct(
  661. "If you're using the current version of our JavaScript SDK and have enabled the [code: BrowserTracing] integration, distributed tracing will work out of the box. To get around possible [link:Browser CORS] issues, define your [code:tracePropagationTargets].",
  662. {
  663. code: <code />,
  664. link: (
  665. <ExternalLink href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" />
  666. ),
  667. }
  668. ),
  669. code: `
  670. Sentry.init({
  671. dsn: "${params.dsn.public}",
  672. integrations: [Sentry.browserTracingIntegration()],
  673. tracePropagationTargets: ["https://myproject.org", /^\/api\//],
  674. });
  675. `,
  676. },
  677. ],
  678. },
  679. ],
  680. verify: () => [
  681. {
  682. type: StepType.VERIFY,
  683. description: tct(
  684. 'Verify that performance monitoring is working correctly with our [link:automatic instrumentation] by simply using your JavaScript application.',
  685. {
  686. link: (
  687. <ExternalLink href="https://docs.sentry.io/platforms/javascript/tracing/instrumentation/automatic-instrumentation/" />
  688. ),
  689. }
  690. ),
  691. },
  692. ],
  693. nextSteps: () => [],
  694. };
  695. const profilingOnboarding: OnboardingConfig<PlatformOptions> = {
  696. ...onboarding,
  697. introduction: params => <MaybeBrowserProfilingBetaWarning {...params} />,
  698. };
  699. export const featureFlagOnboarding: OnboardingConfig = {
  700. install: () => [],
  701. configure: ({featureFlagOptions = {integration: ''}, dsn}) => {
  702. const {integrationName, makeConfigureCode, makeVerifyCode, packageName} =
  703. FEATURE_FLAG_CONFIGURATION_MAP[
  704. featureFlagOptions.integration as keyof typeof FEATURE_FLAG_CONFIGURATION_MAP
  705. ]!;
  706. const installConfig = [
  707. {
  708. language: 'bash',
  709. code: [
  710. {
  711. label: 'npm',
  712. value: 'npm',
  713. language: 'bash',
  714. code: `npm install --save @sentry/browser ${packageName}`,
  715. },
  716. {
  717. label: 'yarn',
  718. value: 'yarn',
  719. language: 'bash',
  720. code: `yarn add @sentry/browser ${packageName}`,
  721. },
  722. ],
  723. },
  724. ];
  725. return [
  726. {
  727. type: StepType.INSTALL,
  728. description: t('Install Sentry and the selected feature flag SDK.'),
  729. configurations: installConfig,
  730. },
  731. {
  732. type: StepType.CONFIGURE,
  733. description: tct(
  734. 'Add [name] to your integrations list, and initialize your feature flag SDK.',
  735. {
  736. name: <code>{integrationName}</code>,
  737. }
  738. ),
  739. configurations: [
  740. {
  741. language: 'JavaScript',
  742. code: makeConfigureCode(dsn.public),
  743. },
  744. ],
  745. },
  746. {
  747. type: StepType.VERIFY,
  748. description: t(
  749. 'Test your setup by evaluating a flag, then capturing an exception. Check the Feature Flags table in Issue Details to confirm that your error event has recorded the flag and its result.'
  750. ),
  751. configurations: [
  752. {
  753. language: 'JavaScript',
  754. code: makeVerifyCode(),
  755. },
  756. ],
  757. },
  758. ];
  759. },
  760. verify: () => [],
  761. nextSteps: () => [],
  762. };
  763. const docs: Docs<PlatformOptions> = {
  764. onboarding,
  765. feedbackOnboardingNpm: feedbackOnboarding,
  766. feedbackOnboardingJsLoader,
  767. replayOnboarding,
  768. replayOnboardingJsLoader,
  769. performanceOnboarding,
  770. crashReportOnboarding,
  771. platformOptions,
  772. profilingOnboarding,
  773. featureFlagOnboarding,
  774. };
  775. export default docs;