diff --git a/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx b/docs/platforms/javascript/common/tracing/span-metrics/examples.mdx
index 3eeebcf11ac8c..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 0ecd7e85ea81c..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,9 +113,47 @@ export function PlatformLink({children, to, supported = [], notSupported = []}:
let href: string;
if (currentPlatformOrGuide) {
- href = currentPlatformOrGuide.url + to.slice(1);
+ 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)}`;
}
+
return {children};
}