SIGN IN SIGN UP

fix(react-router): Resolve the Cloudflare entry in Workers and skip trace meta tags in prerendered pages (#24866)

Three bugs in `@sentry/react-router`, found by running the
`react-router-8-framework` e2e suite on workerd and Bun.

Cloudflare builds resolve with both the `worker` and the `browser`
condition (the Vite plugin sets `workerd, worker, module, browser`,
`wrangler` sets `workerd, worker, browser`), and the exports map listed
`browser` before `worker`, so `worker` was never reached. `import * as
Sentry from '@sentry/react-router'` in a route got the client build, and
`Sentry.startSpan()` / `Sentry.flush()` compiled to `undefined`: loaders
and middleware that call them threw `TypeError: (void 0) is not a
function`. A `workerd` key now comes first and resolves the Cloudflare
entry. Only Cloudflare sets `workerd`, so nothing else changes: moving
`worker` above `browser` would also have switched webpack builds with
`target: 'webworker'`, which set `worker` and `browser`, to the
Cloudflare entry.

On Cloudflare, `react-router build` prerenders pages by running them
through the wrapped Worker, so `injectTraceMetaTags` wrote a build-time
`sentry-trace` and `baggage` into the static HTML. Every visitor of a
prerendered page then continued that one trace with its sampling
decision. Such a path never reaches the handler in production (it is
served as a static file), so a render of a path from the build's
`prerender` list is the build-time prerender, and it now gets no meta
tags. For that, the server build capture also records `prerender`, and
`wrapSentryHandleRequest` registers the capture: on Cloudflare only the
Node server integration did that before, so the build was never captured
there.

An index route has no `path` of its own, so `wrapSentryHandleRequest`
never gave it a route name. On Node, Express names the span first and
hid this. On runtimes without that layer (Bun, and a React Router app on
any non-Express server) the index page kept a URL-sourced name, so its
baggage had no `sentry-transaction`. An index route now takes its
nearest ancestor's path, or `/`. On Node this changes the transaction of
an index page from Express's catch-all `GET *` to `GET /`, which is why
`react-router-7-framework-static` now expects that name.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
J
Jan Peer Stöcklmair committed
425a304da030cdeeb9e6e1eba7a83fdcee328b57
Parent: 8198603
Committed by GitHub <noreply@github.com> on 10/2/2026, 9:51:39 AM