Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b9804e9
chore(onboarding): Prepare JavaScript SDK v11 integration
andreiborza Sep 22, 2026
218bc1e
feat(onboarding): Update JS browser onboarding for SDK v11 (#123878)
msonnb Sep 22, 2026
e2d367f
fix(onboarding): Update Vue onboarding for SDK v11 (#123889)
JPeer264 Sep 22, 2026
cbd6ee4
fix(onboarding): Update Astro requirements for SDK v11 (#123880)
JPeer264 Sep 22, 2026
ed5bfea
feat(onboarding): Offer one Cloudflare platform in the pickers (#123768)
JPeer264 Sep 22, 2026
6f38078
feat(onboarding): Add Remix 2.x support | remove 1.x support (#123882)
JPeer264 Sep 22, 2026
a8bbc9f
feat(onboarding): Update Node onboarding for SDK v11 (#123877)
JPeer264 Sep 22, 2026
cd1d496
feat(onboarding): Update Bun onboarding for SDK v11 (#123797)
JPeer264 Sep 22, 2026
301d492
ref(onboarding): Drop the Express error handler for v11 (#123779)
andreiborza Sep 22, 2026
45627ce
ref(onboarding): Fix the SolidStart server instrument file setup (#12…
andreiborza Sep 22, 2026
444e3b7
ref(onboarding): Update the Hapi onboarding for v11 (#123836)
andreiborza Sep 22, 2026
cf13725
ref(onboarding): Update the Koa onboarding for v11 (#123845)
andreiborza Sep 22, 2026
2c96432
ref(onboarding): Update the Fastify onboarding for v11 (#123826)
andreiborza Sep 22, 2026
edc4873
feat(onboarding): Update Next.js onboarding for SDK v11 (#123911)
chargome Sep 22, 2026
eb18af6
feat(onboarding): Update Deno onboarding for SDK v11 (#123772)
JPeer264 Sep 22, 2026
b9ce9a7
fix(onboarding): Update Ember onboarding for SDK v11 (#123896)
JPeer264 Sep 23, 2026
40c4933
ref(onboarding): Remove Connect onboarding | keep existing Connect pr…
andreiborza Sep 23, 2026
ee6aaab
Use instrument.server.ts for SolidStart agent monitoring
andreiborza Sep 23, 2026
23df131
fix(onboarding): Show Vite setup in Cloudflare logs onboarding (#125298)
JPeer264 Sep 23, 2026
65daf41
fix(onboarding): Show where Cloudflare Pages users put the verify sni…
JPeer264 Sep 23, 2026
c7a9ce2
ref(onboarding/agents): Make dataCollection an explicit step for JS p…
s1gr1d Sep 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions static/app/components/clippedBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -370,5 +370,6 @@ const ClipFade = styled('div')`

const CollapseButton = styled('div')`
text-align: center;
margin-top: ${p => p.theme.space.lg};
margin-bottom: ${p => p.theme.space.lg};
`;
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function CodeBlock(block: Extract<ContentBlock, {type: 'code'}>) {
if ('code' in block) {
return (
<div css={baseBlockStyles}>
<OnboardingCodeSnippet language={block.language}>
<OnboardingCodeSnippet language={block.language} filename={block.filename}>
{block.code}
</OnboardingCodeSnippet>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {
getJsDataCollectionDocsLink,
isJavaScriptPlatform,
} from 'sentry/components/onboarding/gettingStartedDoc/utils';

describe('isJavaScriptPlatform', () => {
it.each([
'javascript',
'javascript-nextjs',
'node',
'node-express',
'bun',
'deno',
'electron',
'capacitor',
'ionic',
])('accepts %s', platform => {
expect(isJavaScriptPlatform(platform)).toBe(true);
});

it.each([
'python',
'python-fastapi',
'php-laravel',
'other',
'go',
// React Native is JavaScript-based, but its docs do not cover `dataCollection`.
'react-native',
undefined,
])('rejects %s', platform => {
expect(isJavaScriptPlatform(platform)).toBe(false);
});
});

describe('getJsDataCollectionDocsLink', () => {
const BASE = 'https://docs.sentry.io/platforms/javascript';

it.each([
['javascript-nextjs', `${BASE}/guides/nextjs/configuration/options/#dataCollection`],
['node', `${BASE}/guides/node/configuration/options/#dataCollection`],
['node-express', `${BASE}/guides/express/configuration/options/#dataCollection`],
['bun', `${BASE}/guides/bun/configuration/options/#dataCollection`],
// Keys whose guide slug differs from the platform key
['node-awslambda', `${BASE}/guides/aws-lambda/configuration/options/#dataCollection`],
[
'node-azurefunctions',
`${BASE}/guides/azure-functions/configuration/options/#dataCollection`,
],
[
'node-gcpfunctions',
`${BASE}/guides/gcp-functions/configuration/options/#dataCollection`,
],
[
'node-cloudflare-workers',
`${BASE}/guides/cloudflare/configuration/options/#dataCollection`,
],
// Legacy key of the merged Cloudflare platform
[
'node-cloudflare-pages',
`${BASE}/guides/cloudflare/configuration/options/#dataCollection`,
],
['ionic', `${BASE}/guides/capacitor/configuration/options/#dataCollection`],
])('maps %s to its guide', (platform, expected) => {
expect(getJsDataCollectionDocsLink(platform)).toBe(expected);
});

it.each(['javascript', 'other', undefined])(
'falls back to the canonical page for %s',
platform => {
expect(getJsDataCollectionDocsLink(platform)).toBe(
`${BASE}/configuration/options/#dataCollection`
);
}
);
});
141 changes: 141 additions & 0 deletions static/app/components/onboarding/gettingStartedDoc/utils/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {Fragment} from 'react';
import {Button} from '@sentry/scraps/button';
import {ExternalLink} from '@sentry/scraps/link';

import type {ContentBlock} from 'sentry/components/onboarding/gettingStartedDoc/contentBlocks/types';
import {
docsFlowVariantParams,
resolveDocsFlowEvent,
Expand Down Expand Up @@ -84,6 +85,146 @@ export function getUploadSourceMapsStep({
};
}

// Platform key families using the JavaScript SDKs. React Native is excluded
// because its docs do not cover `dataCollection`.
const JS_PLATFORM_PREFIXES = [
'javascript',
'node',
'bun',
'deno',
'electron',
'capacitor',
'cordova',
'ionic',
];

/**
* Whether the platform uses a JavaScript SDK that exposes `dataCollection`.
* A positive list, so a future non-JavaScript platform is excluded by default.
*/
export function isJavaScriptPlatform(platformKey: string | null | undefined): boolean {
return (
!!platformKey &&
JS_PLATFORM_PREFIXES.some(
prefix => platformKey === prefix || platformKey.startsWith(`${prefix}-`)
)
);
}

// Platform keys whose docs guide slug is not simply the key minus its family prefix.
const DOCS_GUIDE_SLUG_OVERRIDES: Record<string, string> = {
'node-awslambda': 'aws-lambda',
'node-azurefunctions': 'azure-functions',
'node-gcpfunctions': 'gcp-functions',
// Workers and Pages share the `cloudflare` guide.
'node-cloudflare-workers': 'cloudflare',
'node-cloudflare-pages': 'cloudflare',
ionic: 'capacitor',
};

/**
* The `dataCollection` docs for the platform's own guide, for configs shared
* across JavaScript platforms. Unknown platforms get the canonical page.
*/
export function getJsDataCollectionDocsLink(
platformKey: string | null | undefined
): string {
if (
!platformKey ||
!isJavaScriptPlatform(platformKey) ||
platformKey === 'javascript'
) {
return 'https://docs.sentry.io/platforms/javascript/configuration/options/#dataCollection';
}
const slug =
DOCS_GUIDE_SLUG_OVERRIDES[platformKey] ??
platformKey.replace(/^(javascript|node)-/, '');
return `https://docs.sentry.io/platforms/javascript/guides/${slug}/configuration/options/#dataCollection`;
}

/**
* Shown without an init wrapper because agent and MCP monitoring span several
* init shapes (`Sentry.init`, `Sentry.withSentry`, `instrumentAgentWithSentry`).
*/
export const GEN_AI_DATA_COLLECTION_SNIPPET = `dataCollection: {
genAI: { inputs: false, outputs: false },
},`;

const DEFAULT_DATA_COLLECTION_SNIPPET = `Sentry.init({
// ...
dataCollection: {
userInfo: false,
// other options
},
});`;

/**
* Presents `dataCollection` as its own setup step instead of a commented-out
* override in the init snippet, as the SDK data collection spec requires. Pass
* `collapsible: false` for `GuidedSteps` surfaces, which drop collapsible steps.
*/
export function getDataCollectionStep({
docsLink,
code,
description,
collapsible = true,
}: {
docsLink: string;
code?: string;
collapsible?: boolean;
description?: React.ReactNode;
}): OnboardingStep {
const summary: ContentBlock[] = description
? [{type: 'text', text: description}]
: [
{
type: 'text',
text: t(
'By default, the SDK sends user identity data (IP address, ID, and similar) and other data like HTTP bodies and URL query parameters. This gives you rich debugging context.'
),
},
{
type: 'text',
text: tct(
'The SDK always filters sensitive values whose keys match a built-in denylist, such as [authCode:auth] or [passwordCode:password], and sends [filtered] instead.',
{
authCode: <code />,
passwordCode: <code />,
filtered: <code>[Filtered]</code>,
}
),
},
];

return {
collapsible,
title: t('Control the Data You Send to Sentry (Optional)'),
content: [
...summary,
{
type: 'text',
text: tct(
"To send less data, turn off the categories you don't need in the [code:dataCollection] option. For the full list of categories and their defaults, see [link:the dataCollection options].",
{
code: <code />,
link: <ExternalLink href={docsLink} />,
}
),
},
{
type: 'code',
tabs: [
{
label: 'JavaScript',
language: 'javascript',
code: code ?? DEFAULT_DATA_COLLECTION_SNIPPET,
},
],
},
],
};
}

const SENTRY_INSTRUMENT_SKILL_URL = 'https://skills.sentry.dev/instrument';

function CopyPromptButton({prompt}: {prompt: string}) {
Expand Down
11 changes: 10 additions & 1 deletion static/app/components/onboarding/productSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,17 @@ export function getDisabledProducts(organization: Organization): DisabledProduct
// NOTE: Please keep the prefix in alphabetical order
export const platformProductAvailability = {
'apple-macos': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
bun: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS],
bun: [
ProductSolution.PERFORMANCE_MONITORING,
ProductSolution.LOGS,
ProductSolution.METRICS,
],
capacitor: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS],
deno: [
ProductSolution.PERFORMANCE_MONITORING,
ProductSolution.LOGS,
ProductSolution.METRICS,
],
dotnet: [
ProductSolution.PERFORMANCE_MONITORING,
ProductSolution.PROFILING,
Expand Down
13 changes: 11 additions & 2 deletions static/app/components/onboarding/scm/scmPlatformHelpers.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,18 @@ describe('platformOptionGroups', () => {
);
});

it('keeps every platform exactly once across sections', () => {
it('leaves hidden platforms out of the dropdown', () => {
expect(
otherGroup!.options.some(option => option.value === 'node-cloudflare-pages')
).toBe(false);
expect(
platformOptions.filter(option => option.label === 'Cloudflare (Node)')
).toHaveLength(1);
});

it('keeps every offered platform exactly once across sections', () => {
const values = platformOptions.map(option => option.value);
expect(new Set(values).size).toBe(values.length);
expect(values).toHaveLength(platforms.length);
expect(values).toHaveLength(platforms.filter(platform => !platform.hidden).length);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const platformOptionGroups = [
{
label: t('Other platforms'),
options: platforms
.filter(platform => !platform.hidden)
.filter(platform => !popularPlatformCategories.has(platform.id))
.toSorted((a, b) => comparePlatformNames(a.name, b.name))
.map(toPlatformOption),
Expand Down
25 changes: 15 additions & 10 deletions static/app/data/platformCategories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ export const withLoggingOnboarding = new Set<PlatformKey>([
'cocoa-objc',
'cocoa-swift',
'dart',
'deno',
'dotnet',
'dotnet-aspnet',
'dotnet-aspnetcore',
Expand Down Expand Up @@ -416,6 +417,8 @@ export const withMetricsOnboarding = new Set<PlatformKey>([
'apple',
'apple-ios',
'apple-macos',
'bun',
'deno',
'dotnet',
'dotnet-aspnet',
'dotnet-aspnetcore',
Expand Down Expand Up @@ -856,16 +859,7 @@ export const featureFlagDrawerPlatforms: readonly PlatformKey[] = [
'react-native',
];

export const agentMonitoringPlatforms: ReadonlySet<PlatformKey> = new Set([
...platformKeys.filter(id => id.startsWith('javascript')),
...platformKeys.filter(id => id.startsWith('node')),
...platformKeys.filter(id => id.startsWith('python')),
'deno',
'bun',
'php-laravel',
]);

export const javascriptMetaFrameworks: readonly PlatformKey[] = [
const javascriptMetaFrameworks: readonly PlatformKey[] = [
'javascript-astro',
'javascript-nextjs',
'javascript-nuxt',
Expand All @@ -876,8 +870,19 @@ export const javascriptMetaFrameworks: readonly PlatformKey[] = [
'javascript-tanstackstart-react',
] as const;

export const agentMonitoringPlatforms: ReadonlySet<PlatformKey> = new Set([
...javascriptMetaFrameworks,
...platformKeys.filter(id => id.startsWith('node')),
...platformKeys.filter(id => id.startsWith('python')),
'deno',
'bun',
'php-laravel',
]);

export const mcpMonitoringPlatforms: ReadonlySet<PlatformKey> = new Set([
...javascriptMetaFrameworks,
...platformKeys.filter(id => id.startsWith('node')),
...platformKeys.filter(id => id.startsWith('python')),
'bun',
'deno',
]);
3 changes: 0 additions & 3 deletions static/app/data/platformPickerCategories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ const server = new Set<PlatformKey>([
'kotlin',
'native',
'node',
'node-cloudflare-pages',
'node-cloudflare-workers',
'node-connect',
'node-express',
'node-fastify',
'node-hapi',
Expand Down Expand Up @@ -158,7 +156,6 @@ const serverless = new Set<PlatformKey>([
'node-awslambda',
'node-azurefunctions',
'node-gcpfunctions',
'node-cloudflare-pages',
'node-cloudflare-workers',
'python-awslambda',
'python-gcpfunctions',
Expand Down
8 changes: 6 additions & 2 deletions static/app/data/platforms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -445,14 +445,16 @@ export const platforms: PlatformIntegration[] = [
},
{
id: 'node-cloudflare-pages',
name: 'Cloudflare Pages',
name: 'Cloudflare (Node)',
type: 'framework',
language: 'node',
link: 'https://docs.sentry.io/platforms/javascript/guides/cloudflare/',
// Merged into `node-cloudflare-workers`, which is the Cloudflare platform.
hidden: true,
Comment thread
cursor[bot] marked this conversation as resolved.
},
{
id: 'node-cloudflare-workers',
name: 'Cloudflare Workers',
name: 'Cloudflare (Node)',
type: 'framework',
language: 'node',
link: 'https://docs.sentry.io/platforms/javascript/guides/cloudflare/',
Expand All @@ -463,6 +465,8 @@ export const platforms: PlatformIntegration[] = [
type: 'framework',
language: 'node',
link: 'https://docs.sentry.io/platforms/javascript/guides/connect/',
// Version 11 of the SDK removed the Connect instrumentation.
hidden: true,
Comment thread
cursor[bot] marked this conversation as resolved.
},
{
id: 'node-express',
Expand Down
Loading
Loading