import ExternalLink from 'sentry/components/links/externalLink'; import crashReportCallout from 'sentry/components/onboarding/gettingStartedDoc/feedback/crashReportCallout'; import widgetCallout from 'sentry/components/onboarding/gettingStartedDoc/feedback/widgetCallout'; import TracePropagationMessage from 'sentry/components/onboarding/gettingStartedDoc/replay/tracePropagationMessage'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step'; import type { Docs, DocsParams, OnboardingConfig, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {getUploadSourceMapsStep} from 'sentry/components/onboarding/gettingStartedDoc/utils'; import { getCrashReportModalConfigDescription, getCrashReportModalInstallDescriptionJavaScript, getCrashReportModalIntroduction, getFeedbackConfigureDescription, getFeedbackSDKSetupSnippet, } from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding'; import { getReplayConfigureDescription, getReplaySDKSetupSnippet, } from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding'; import {t, tct} from 'sentry/locale'; type Params = DocsParams; const getConfigureSnippet = (params: Params) => ` import * as Sentry from "@sentry/electron"; Sentry.init({ dsn: "${params.dsn}", });`; const getMetricsConfigureSnippet = (params: Params) => ` import * as Sentry from '@sentry/electron/main'; // main process init Sentry.init({ dsn: "${params.dsn}", _experiments: { metricsAggregator: true, }, });`; const getMetricsVerifySnippet = () => ` // Add 4 to a counter named 'hits' Sentry.metrics.increment('hits', 4);`; const getInstallConfig = () => [ { code: [ { label: 'npm', value: 'npm', language: 'bash', code: 'npm install --save @sentry/electron', }, { label: 'yarn', value: 'yarn', language: 'bash', code: 'yarn add @sentry/electron', }, ], }, ]; const onboarding: OnboardingConfig = { install: () => [ { type: StepType.INSTALL, description: t('Add the Sentry Electron SDK package as a dependency:'), configurations: getInstallConfig(), }, ], configure: params => [ { type: StepType.CONFIGURE, description: tct( `You need to call [codeInit:Sentry.init] in the [codeMain:main] process and in every [codeRenderer:renderer] process you spawn. For more details about configuring the Electron SDK [docsLink:click here].`, { codeInit: , codeMain: , codeRenderer: , docsLink: ( ), } ), configurations: [ { language: 'javascript', code: getConfigureSnippet(params), }, ], }, getUploadSourceMapsStep({ guideLink: 'https://docs.sentry.io/platforms/javascript/guides/electron/sourcemaps/', ...params, }), ], verify: () => [ { type: StepType.VERIFY, description: t( `One way to verify your setup is by intentionally causing an error that breaks your application.` ), configurations: [ { description: t( `Calling an undefined function will throw a JavaScript exception:` ), language: 'javascript', code: 'myUndefinedFunction();', }, { description: t( `With Electron you can test native crash reporting by triggering a crash:` ), language: 'javascript', code: 'process.crash();', }, ], additionalInfo: t( 'You may want to try inserting these code snippets into both your main and any renderer processes to verify Sentry is operational in both.' ), }, ], }; const replayOnboarding: OnboardingConfig = { install: () => [ { type: StepType.INSTALL, description: tct( 'For the Session Replay to work, you must have the framework SDK (e.g. [code:@sentry/electron]) installed, minimum version 4.2.0.', { code: , } ), configurations: getInstallConfig(), }, ], configure: (params: Params) => [ { type: StepType.CONFIGURE, description: getReplayConfigureDescription({ link: 'https://docs.sentry.io/platforms/javascript/guides/electron/session-replay/', }), configurations: [ { code: [ { label: 'JavaScript', value: 'javascript', language: 'javascript', code: getReplaySDKSetupSnippet({ importStatement: `import * as Sentry from "@sentry/electron/renderer";`, dsn: params.dsn, mask: params.replayOptions?.mask, block: params.replayOptions?.block, }), }, ], additionalInfo: , }, ], }, ], verify: () => [], nextSteps: () => [], }; const customMetricsOnboarding: OnboardingConfig = { install: () => [ { type: StepType.INSTALL, description: tct( 'You need a minimum version [codeVersion:4.17.0] of [codePackage:@sentry/electron].', { codeVersion: , codePackage: , } ), configurations: getInstallConfig(), }, ], configure: params => [ { type: StepType.CONFIGURE, description: tct( 'To enable capturing metrics, you first need to add the [codeIntegration:metricsAggregator] experiment to your [codeNamespace:Sentry.init] call in your main process.', { codeIntegration: , codeNamespace: , } ), configurations: [ { code: [ { label: 'JavaScript', value: 'javascript', language: 'javascript', code: getMetricsConfigureSnippet(params), }, ], }, ], }, ], verify: () => [ { type: StepType.VERIFY, description: tct( "Then you'll be able to add metrics as [codeCounters:counters], [codeSets:sets], [codeDistribution:distributions], and [codeGauge:gauges]. These are available under the [codeNamespace:Sentry.metrics] namespace. This API is available in both renderer and main processes. Try out this example:", { codeCounters: , codeSets: , codeDistribution: , codeGauge: , codeNamespace: , } ), configurations: [ { code: [ { label: 'JavaScript', value: 'javascript', language: 'javascript', code: getMetricsVerifySnippet(), }, ], }, { description: t( 'With a bit of delay you can see the data appear in the Sentry UI.' ), }, { description: tct( 'Learn more about metrics and how to configure them, by reading the [docsLink:docs].', { docsLink: ( ), } ), }, ], }, ], }; const feedbackOnboarding: OnboardingConfig = { install: () => [ { type: StepType.INSTALL, description: tct( 'For the User Feedback integration to work, you must have the Sentry browser SDK package, or an equivalent framework SDK (e.g. [code:@sentry/electron]) installed, minimum version 7.85.0.', { code: , } ), configurations: getInstallConfig(), }, ], configure: (params: Params) => [ { type: StepType.CONFIGURE, description: getFeedbackConfigureDescription({ linkConfig: 'https://docs.sentry.io/platforms/javascript/guides/electron/user-feedback/configuration/', linkButton: 'https://docs.sentry.io/platforms/javascript/guides/electron/user-feedback/configuration/#bring-your-own-button', }), configurations: [ { code: [ { label: 'JavaScript', value: 'javascript', language: 'javascript', code: getFeedbackSDKSetupSnippet({ importStatement: `import * as Sentry from "@sentry/electron/renderer";`, dsn: params.dsn, feedbackOptions: params.feedbackOptions, }), }, ], }, ], additionalInfo: crashReportCallout({ link: 'https://docs.sentry.io/platforms/javascript/guides/electron/user-feedback/#crash-report-modal', }), }, ], verify: () => [], nextSteps: () => [], }; const crashReportOnboarding: OnboardingConfig = { introduction: () => getCrashReportModalIntroduction(), install: (params: Params) => [ { type: StepType.INSTALL, description: getCrashReportModalInstallDescriptionJavaScript(), configurations: [ { code: [ { label: 'JavaScript', value: 'javascript', language: 'javascript', code: `const { init, showReportDialog } = require("@sentry/electron"); init({ dsn: "${params.dsn}", beforeSend(event) { // Check if it is an exception, if so, show the report dialog // Note that this only will work in the renderer process, it's a noop on the main process if (event.exception && event.event_id) { showReportDialog({ eventId: event_id }); } return event; }, });`, }, ], }, ], }, ], configure: () => [ { type: StepType.CONFIGURE, description: getCrashReportModalConfigDescription({ link: 'https://docs.sentry.io/platforms/javascript/guides/electron/user-feedback/configuration/#crash-report-modal', }), additionalInfo: widgetCallout({ link: 'https://docs.sentry.io/platforms/javascript/guides/electron/user-feedback/#user-feedback-widget', }), }, ], verify: () => [], nextSteps: () => [], }; const docs: Docs = { onboarding, feedbackOnboardingNpm: feedbackOnboarding, replayOnboardingNpm: replayOnboarding, customMetricsOnboarding, crashReportOnboarding, }; export default docs;