From b9bbc2aed6ecc6a3d292240612b521f85ec93225 Mon Sep 17 00:00:00 2001 From: Logesh Date: Sat, 7 Mar 2026 04:02:23 +0530 Subject: [PATCH 1/2] fix(open-file): strip Next.js App Router virtual path segments before editor launch Next.js App Router dev server injects `/(app-pages-browser)/` into stack frame file paths. Passing this corrupted path to `/__nextjs_launch-editor` causes the editor to receive a path that doesn't exist on disk, so "Open in editor" silently fails for all App Router users. Strip the virtual segment before building the URLSearchParams so the endpoint receives the real file path. Fixes #215 Co-Authored-By: Claude Sonnet 4.6 --- packages/react-grab/src/utils/open-file.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/react-grab/src/utils/open-file.ts b/packages/react-grab/src/utils/open-file.ts index c6547084e..c896a6b9c 100644 --- a/packages/react-grab/src/utils/open-file.ts +++ b/packages/react-grab/src/utils/open-file.ts @@ -1,12 +1,19 @@ import { checkIsNextProject } from "../core/context.js"; import { buildOpenFileUrl } from "./build-open-file-url.js"; +// Next.js App Router dev server injects a virtual path segment into stack frames. +// Strip it before passing the path to the launch-editor endpoint. +const stripAppRouterVirtualSegments = (filePath: string): string => + filePath.replace(/\/\(app-pages-browser\)\//g, "/"); + const tryDevServerOpen = async ( filePath: string, lineNumber: number | undefined, ): Promise => { const isNextProject = checkIsNextProject(); - const params = new URLSearchParams({ file: filePath }); + const params = new URLSearchParams({ + file: isNextProject ? stripAppRouterVirtualSegments(filePath) : filePath, + }); const lineKey = isNextProject ? "line1" : "line"; const columnKey = isNextProject ? "column1" : "column"; From 4455b4158cfc640df381df8787df2a2c7b39885d Mon Sep 17 00:00:00 2001 From: Logesh Date: Sat, 7 Mar 2026 05:12:01 +0530 Subject: [PATCH 2/2] fix(open-file): normalize path in fallback URL path too --- packages/react-grab/src/utils/open-file.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/react-grab/src/utils/open-file.ts b/packages/react-grab/src/utils/open-file.ts index c896a6b9c..474115b24 100644 --- a/packages/react-grab/src/utils/open-file.ts +++ b/packages/react-grab/src/utils/open-file.ts @@ -32,15 +32,19 @@ export const openFile = async ( lineNumber: number | undefined, transformUrl?: (url: string, filePath: string, lineNumber?: number) => string, ): Promise => { + const normalizedPath = checkIsNextProject() + ? stripAppRouterVirtualSegments(filePath) + : filePath; + const wasOpenedByDevServer = await tryDevServerOpen( - filePath, + normalizedPath, lineNumber, ).catch(() => false); if (wasOpenedByDevServer) return; - const rawUrl = buildOpenFileUrl(filePath, lineNumber); + const rawUrl = buildOpenFileUrl(normalizedPath, lineNumber); const url = transformUrl - ? transformUrl(rawUrl, filePath, lineNumber) + ? transformUrl(rawUrl, normalizedPath, lineNumber) : rawUrl; window.open(url, "_blank", "noopener,noreferrer"); };