Skip to content
Open
Changes from all commits
Commits
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
122 changes: 104 additions & 18 deletions app/platform-redirect/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,33 @@ export default async function Page(props: {

// get rid of irrelevant platforms for the `next` path
const platformList = extractPlatforms(rootNode).filter(platform_ => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be a lot more freeing to switch the type of this list from "platforms" to "platforms or guides"

from there, I see two options:

  1. the nesting will either be rendered from a flat list similar to now,
    preferably with some flag indicating that it should be nested,
    which will also open the door for a more generic solution without the hardcoded JS logic

OR

  1. keep the the "platforms" type along with an inner filter over its guides, I platform would be retained in the filter if it has at least one relevant guide (the Dart/Flutter situation).
    Then adjust the rendering accordingly

I tend to prefer approach 2, much cleaner

const node = nodeForPath(rootNode, [
// First check the main platform path
let node = nodeForPath(rootNode, [
'platforms',
platform_.key,
...pathname.split('/').filter(Boolean),
]);

// If not found, check if it's a guide (like dart/guides/flutter)
if (!node && platform_.guides) {
for (const guide of platform_.guides) {
node = nodeForPath(rootNode, [
'platforms',
platform_.key,
'guides',
guide.name,
...pathname.split('/').filter(Boolean),
]);
if (node) {
// Create a copy of the platform with the guide URL to avoid mutating the original
const platformCopy = {...platform_, url: guide.url};
// Update the platform reference to use the copy
Object.assign(platform_, platformCopy);
break;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Platform URL Mutation Causes Framework Inheritance Issues

The code mutates the original platform_ object's url property within the filter callback, despite the stated intent to avoid mutation. This modifies shared state from extractPlatforms(rootNode) and can lead to unexpected side effects. As a result, JavaScript frameworks derived from a mutated javascriptPlatform may inherit an incorrect, guide-specific URL instead of the main platform URL.

Additional Locations (1)

Fix in Cursor Fix in Web

}
}
}

// extract title and description for displaying it on page
if (node && title === defaultTitle && pathname.length > 0) {
title = node.frontmatter.title ?? title;
Expand All @@ -54,18 +75,78 @@ export default async function Page(props: {
return !!node;
});

if (platformList.length === 0) {
// For JavaScript platforms, also include individual frameworks that support the content
const expandedPlatformList = [...platformList];

// Find JavaScript platform and add its supported frameworks
// Only use JavaScript platform if it's already in the filtered list (has relevant content)
const javascriptPlatform = platformList.find(p => p.key === 'javascript');

if (
javascriptPlatform &&
(pathname.startsWith('/session-replay/') ||
pathname.startsWith('/tracing/') ||
pathname.startsWith('/profiling/') ||
pathname.startsWith('/logs/'))
) {
// Get the JavaScript page to check which frameworks are supported
const jsPageNode = nodeForPath(rootNode, [
'platforms',
'javascript',
...pathname.split('/').filter(Boolean),
]);

if (jsPageNode && jsPageNode.frontmatter.notSupported) {
const notSupported = jsPageNode.frontmatter.notSupported;

// Remove JavaScript from the main list temporarily
const otherPlatforms = expandedPlatformList.filter(p => p.key !== 'javascript');

// Add supported JavaScript frameworks as separate entries
const jsFrameworks: typeof platformList = [];
javascriptPlatform.guides?.forEach(guide => {
const guideKey = `javascript.${guide.name}`;
if (!notSupported.includes(guideKey)) {
jsFrameworks.push({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels like a lot of repetition : )

key: guideKey,
name: guide.name,
type: 'platform' as const,
url: javascriptPlatform.url,
title: guide.title,
caseStyle: guide.caseStyle,
sdk: guide.sdk,
fallbackPlatform: guide.fallbackPlatform,
language: guide.language,
categories: guide.categories,
keywords: guide.keywords,
guides: [],
integrations: [],
icon: `javascript-${guide.name}`,
});
}
});

// Rebuild the list with JavaScript and its frameworks at the end
expandedPlatformList.length = 0; // Clear the array
expandedPlatformList.push(...otherPlatforms); // Add other platforms first
expandedPlatformList.push(javascriptPlatform); // Add JavaScript platform
expandedPlatformList.push(...jsFrameworks); // Add JavaScript frameworks last
}
}

if (expandedPlatformList.length === 0) {
// try to redirect the user to the page directly, might result in 404
return redirect(next);
}

const requestedPlatform = Array.isArray(platform) ? platform[0] : platform;
if (requestedPlatform) {
const isValidPlatform = platformList.some(
const validPlatform = expandedPlatformList.find(
p => p.key === requestedPlatform?.toLowerCase()
);
if (isValidPlatform) {
return redirect(`/platforms/${requestedPlatform}${pathname}`);
if (validPlatform) {
// Use the platform's URL (which may have been updated to point to a guide)
return redirect(`${validPlatform.url}${pathname}`);
}
}

Expand All @@ -82,19 +163,24 @@ export default async function Page(props: {
<Alert>{platformInfo}</Alert>

<ul>
{platformList.map(p => (
<li key={p.key}>
<SmartLink to={`/platforms/${p.key}${pathname}`}>
<PlatformIcon
size={16}
platform={p.icon ?? p.key}
style={{marginRight: '0.5rem'}}
format="sm"
/>
<h4 style={{display: 'inline-block'}}>{p.title}</h4>
</SmartLink>
</li>
))}
{expandedPlatformList.map(p => {
// Check if this is a JavaScript framework (has javascript. prefix)
const isJSFramework = p.key.startsWith('javascript.');

return (
<li key={p.key} style={{marginLeft: isJSFramework ? '20px' : '0'}}>
<SmartLink to={`${p.url}${pathname}`}>
<PlatformIcon
size={16}
platform={p.icon ?? p.key}
style={{marginRight: '0.5rem'}}
format="sm"
/>
<h4 style={{display: 'inline-block'}}>{p.title}</h4>
</SmartLink>
</li>
);
})}
</ul>
</DocPage>
);
Expand Down
Loading