From dd6d608424c76cac79f1e4a59557a32c7ffd6ab8 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 10 Nov 2025 13:18:04 +0100 Subject: [PATCH 1/4] fix slice --- src/components/platformLink.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/platformLink.tsx b/src/components/platformLink.tsx index 0ecd7e85ea81c..c54d32bed64d6 100644 --- a/src/components/platformLink.tsx +++ b/src/components/platformLink.tsx @@ -73,9 +73,10 @@ export function PlatformLink({children, to, supported = [], notSupported = []}: let href: string; if (currentPlatformOrGuide) { - href = currentPlatformOrGuide.url + to.slice(1); + href = currentPlatformOrGuide.url + (to.startsWith('/') ? to.slice(1) : to); } else { href = `/platform-redirect/?next=${encodeURIComponent(to)}`; } + return {children}; } From 6fb26d07237cbb9c610e44d9835ce208be8bfe19 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 10 Nov 2025 13:22:00 +0100 Subject: [PATCH 2/4] fix queue links --- .../javascript/common/tracing/span-metrics/examples.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx b/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx index 3eeebcf11ac8c..616182527efcd 100644 --- a/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx +++ b/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx @@ -247,7 +247,7 @@ Where to put this in your app: -This example demonstrates proper queue instrumentation patterns. For more details on instrumenting queues, see the Queues Module documentation. +This example demonstrates proper queue instrumentation patterns. For more details on instrumenting queues, see the Queues Module documentation. From 928e626a82b9e6212bac55b5764e86931def213e Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 10 Nov 2025 13:41:05 +0100 Subject: [PATCH 3/4] ... --- .../javascript/common/tracing/span-metrics/examples.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx b/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx index 616182527efcd..5c0223efab900 100644 --- a/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx +++ b/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx @@ -247,7 +247,7 @@ Where to put this in your app: -This example demonstrates proper queue instrumentation patterns. For more details on instrumenting queues, see the Queues Module documentation. +This example demonstrates proper queue instrumentation patterns. For more details on instrumenting queues, see the Queues Module documentation. From edbf1358ef65658cd03fd46d9bae63ae13286fca Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Mon, 10 Nov 2025 14:42:29 +0100 Subject: [PATCH 4/4] different approach --- .../common/tracing/span-metrics/examples.mdx | 2 +- src/components/platformLink.tsx | 91 +++++++++++++++++-- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx b/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx index 5c0223efab900..7dfb41385a7fb 100644 --- a/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx +++ b/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx @@ -247,7 +247,7 @@ Where to put this in your app: -This example demonstrates proper queue instrumentation patterns. For more details on instrumenting queues, see the Queues Module documentation. +This example demonstrates proper queue instrumentation patterns. For more details on instrumenting queues, see the Queues Module documentation. diff --git a/src/components/platformLink.tsx b/src/components/platformLink.tsx index c54d32bed64d6..5e7a0fc3ddcd0 100644 --- a/src/components/platformLink.tsx +++ b/src/components/platformLink.tsx @@ -1,4 +1,4 @@ -import {getCurrentPlatformOrGuide, getPlatform} from 'sentry-docs/docTree'; +import {getCurrentPlatformOrGuide, getPlatform, nodeForPath} from 'sentry-docs/docTree'; import {serverContext} from 'sentry-docs/serverContext'; import {Platform, PlatformGuide} from 'sentry-docs/types'; @@ -9,11 +9,44 @@ function getPlatformsWithFallback( platformOrGuide: Platform | PlatformGuide ) { const result = [platformOrGuide.key]; - let curPlatform: Platform | PlatformGuide | undefined = platformOrGuide; - while (curPlatform?.fallbackPlatform) { - result.push(curPlatform.fallbackPlatform); - curPlatform = getPlatform(rootNode, curPlatform.fallbackPlatform); + let curPlatformOrGuide: Platform | PlatformGuide | undefined = platformOrGuide; + + while (curPlatformOrGuide) { + let fallbackKey: string | undefined; + + // For guides, check fallbackGuide first + if ('fallbackGuide' in curPlatformOrGuide && curPlatformOrGuide.fallbackGuide) { + // fallbackGuide is the full key like "javascript.node" + result.push(curPlatformOrGuide.fallbackGuide); + // After the guide fallback, also check the guide's parent platform + const guidePlatform = getPlatform(rootNode, curPlatformOrGuide.platform); + if (guidePlatform?.fallbackPlatform) { + result.push(guidePlatform.fallbackPlatform); + } + break; + } + // For JavaScript guides without explicit fallbackGuide, check if they're server-side + // If so, include node in the fallback chain + else if ( + 'platform' in curPlatformOrGuide && + curPlatformOrGuide.platform === 'javascript' && + (curPlatformOrGuide.categories?.includes('server') || + curPlatformOrGuide.categories?.includes('serverless')) + ) { + // Include node platform for server-side JavaScript guides + result.push('node'); + break; + } + // For platforms, check fallbackPlatform + else if (curPlatformOrGuide.fallbackPlatform) { + fallbackKey = curPlatformOrGuide.fallbackPlatform; + result.push(fallbackKey); + curPlatformOrGuide = getPlatform(rootNode, fallbackKey); + } else { + break; + } } + return result; } @@ -33,12 +66,19 @@ const isSupported = ( type Props = { children: React.ReactNode; + fallbackPlatform?: string; notSupported?: string[]; supported?: string[]; to?: string; }; -export function PlatformLink({children, to, supported = [], notSupported = []}: Props) { +export function PlatformLink({ + children, + to, + supported = [], + notSupported = [], + fallbackPlatform, +}: Props) { if (!to) { return children; } @@ -73,7 +113,44 @@ export function PlatformLink({children, to, supported = [], notSupported = []}: let href: string; if (currentPlatformOrGuide) { - href = currentPlatformOrGuide.url + (to.startsWith('/') ? to.slice(1) : to); + if (fallbackPlatform) { + const pathParts = to.split('/').filter(Boolean); + const platformsToCheck = getPlatformsWithFallback(rootNode, currentPlatformOrGuide); + let contentExistsInChain = false; + + for (const platformKey of platformsToCheck) { + let platformPath: string[]; + if (platformKey.includes('.')) { + const [platform, guide] = platformKey.split('.'); + platformPath = ['platforms', platform, 'guides', guide]; + } else { + platformPath = ['platforms', platformKey]; + } + + const targetNode = nodeForPath(rootNode, [...platformPath, ...pathParts]); + + if (targetNode) { + contentExistsInChain = true; + break; + } + } + + // If content exists anywhere in the natural fallback chain, use current platform URL + // Otherwise, use the explicit fallbackPlatform + if (contentExistsInChain) { + href = currentPlatformOrGuide.url + to.slice(1); + } else { + const fallbackPlatformObj = getPlatform(rootNode, fallbackPlatform); + if (fallbackPlatformObj) { + href = fallbackPlatformObj.url + to.slice(1); + } else { + // Fallback platform not found, construct URL manually + href = `/platforms/${fallbackPlatform}${to}`; + } + } + } else { + href = currentPlatformOrGuide.url + to.slice(1); + } } else { href = `/platform-redirect/?next=${encodeURIComponent(to)}`; }