Repository navigation
feat(nextjs): Add a tunnel route handler that sends only the event payload to Sentry - #25456
Conversation
fb12663 to
de8fd3d
Compare
size-limit report 📦
|
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit de8fd3d. Configure here.
logaretm
left a comment
There was a problem hiding this comment.
Tiny issue and a small FYI, LGTM and looks nice!
| } | ||
|
|
||
| // Like the SDK transports, so that the forward creates no spans, breadcrumbs or trace headers. | ||
| return suppressTracing(() => handleTunnelRequest({ request, allowedDsns })); |
There was a problem hiding this comment.
FYI: This will lose the actual client IP, so relay will think the server is the user. Another issue is it parses the whole payload only to re-serialize it again.
This is pr-existing in the current tunnel utils, I'm handling both concern in my project stack atm so let's keep it. Just an FYI.
Check #25199 for reference.
There was a problem hiding this comment.
Good point, thanks! I'll leave this as-is here so you can handle this in your stack.
| projectDir: string = process.cwd(), | ||
| ): string | undefined { | ||
| // Like Next.js, ignore `src/app` if there is a root `app` directory. | ||
| const appDir = ['app', 'src/app'].find(dir => getStats(path.join(projectDir, dir))?.isDirectory()); |
There was a problem hiding this comment.
If the root has pages/ and the handler is in src/app/sentry-tunnel/route.ts, this picks src/app and enables handler mode.
Next.js ignores src/ when app or pages exists in the root, so /sentry-tunnel 404s and all events are lost. Checking for a root pages too fixes it:
| const appDir = ['app', 'src/app'].find(dir => getStats(path.join(projectDir, dir))?.isDirectory()); | |
| const hasRootDir = ['app', 'pages'].some(dir => getStats(path.join(projectDir, dir))?.isDirectory()); | |
| const appDir = hasRootDir ? 'app' : 'src/app'; |
There was a problem hiding this comment.
I tested this with a root pages/ and src/app/sentry-tunnel/route.ts on Next 14.2 and 15.5 (webpack/Turbopack, build/dev). /sentry-tunnel is served from src/app, and the root pages still work.
The docs say:
src/apporsrc/pageswill be ignored if app or pages are present in the root directory.
But the code resolves pages and app separately (find-pages-dir): a root pages/ hides only src/pages/, and a root app/ hides only src/app/. Since Next 16, this mixed layout fails the build anyway (vercel/next.js#83416).
With the suggestion, the SDK wouldn't detect the file in those 14/15 apps, so handler mode would quietly stay off and the tunnel would keep forwarding all headers. So I kept the detection and added a test for this case.
…route-handler Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…route-handler Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tunnel route handlers (`@sentry/nextjs/tunnel` and TanStack Start's `createSentryTunnelRoute`) now check the request size before they read the body. A request larger than 20 MiB gets a 413, and a request without `Content-Length` gets a 411. So one request can no longer make the server hold more than 20 MiB in memory. SDK envelopes are much smaller than this limit, so normal traffic does not change. Checking the header is enough, because the HTTP server stops reading the body at `Content-Length`. Stacked on #25456.

Today,
tunnelRouterewrites tunnel requests to Sentry as a proxy. This PR adds an opt-in handler mode: ifapp/sentry-tunnel/route.ts(orsrc/app/sentry-tunnel/route.ts) exists, the SDK rewrites the tunnel route internally to it, and the handler sends only the event payload to Sentry. Without the file, nothing changes.tunnelRouteoption, a warning is shown.beforeFiles, so a public file or page at the tunnel path cannot shadow it.createSentryTunnelRoute({ allowedDsns })which covers other DSNs.Tested with unit tests, two new
nextjs-16-tunnelvariants (Turbopack/Node.js, webpack/edge) that also check the forwarded headers.Also tested with a manual Vercel deploy on Next.js 14-16.
Fixes JS-3927