From 97c8c14350c81b6cbfb6484fade5efc486dbc31a Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 09:30:59 +0000 Subject: [PATCH 1/9] docs(cloudflare): Add a React Router on Cloudflare Workers guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Jan VamPeer Stöcklmair --- .../cloudflare/frameworks/react-router.mdx | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx new file mode 100644 index 00000000000000..44352944f9e669 --- /dev/null +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx @@ -0,0 +1,149 @@ +--- +title: React Router on Cloudflare +description: "Learn how to instrument your React Router framework app on Cloudflare Workers with Sentry." +--- + + + +This guide covers React Router apps in [framework mode](https://reactrouter.com/start/modes#framework) that you deploy to Cloudflare Workers with the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/). For Node.js deployments, see the [React Router guide](/platforms/javascript/guides/react-router/). For Shopify Oxygen, see [Hydrogen with React Router](/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router/). + +## Prerequisites + +Before you begin, make sure you have: + +- A Sentry [account](https://sentry.io/signup/) and [project](/product/projects/) +- A React Router app configured for Cloudflare Workers, for example one created with Cloudflare's [React Router guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/react-router/) + +## Install the SDKs + +Install `@sentry/react-router` for the client and the React Router server entry, and `@sentry/cloudflare` for the Worker: + +```bash {tabTitle:npm} +npm install @sentry/react-router @sentry/cloudflare +``` + +```bash {tabTitle:yarn} +yarn add @sentry/react-router @sentry/cloudflare +``` + +```bash {tabTitle:pnpm} +pnpm add @sentry/react-router @sentry/cloudflare +``` + +## Configure Wrangler + + + +## Instrument the Worker + +The Sentry Cloudflare Vite plugin wraps your Worker entry with `withSentry` at build time, so you don't need to change `workers/app.ts`. Add it to your Vite config after the Cloudflare and React Router plugins: + +```typescript {filename:vite.config.ts} +import { cloudflare } from "@cloudflare/vite-plugin"; +import { reactRouter } from "@react-router/dev/vite"; +import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [ + cloudflare({ viteEnvironment: { name: "ssr" } }), + reactRouter(), + sentryCloudflareVitePlugin(), + ], +}); +``` + +Then, create an `instrument.server.ts` file next to the Worker entry that `main` in your Wrangler configuration points to. For example, if `main` is `./workers/app.ts`, create `workers/instrument.server.ts`: + +```typescript {filename:workers/instrument.server.ts} +import { defineCloudflareOptions } from "@sentry/cloudflare"; + +export default defineCloudflareOptions({ + dsn: "___PUBLIC_DSN___", + + // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing. + // Learn more at + // https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/options/#tracesSampleRate + tracesSampleRate: 1.0, +}); +``` + +For more on the plugin and its options, see the Vite plugin page. + +## Instrument the Server Entry + +Without React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation), the SDK only names a request after its route when React Router renders a document. Resource routes, and errors in loaders and actions, end up with a generic `GET` name. Export `instrumentations` from `app/entry.server.tsx` to create spans for all loaders, actions, middleware, and request handlers, named after their route. + +On Workers, import from `@sentry/react-router/cloudflare`. Wrap `handleRequest` with `wrapSentryHandleRequest`, pass the rendered stream through `injectTraceMetaTags` to connect server and client traces, and report errors from `handleError`: + +```tsx {filename:app/entry.server.tsx} +import { captureException } from "@sentry/cloudflare"; +import * as Sentry from "@sentry/react-router/cloudflare"; +import { isbot } from "isbot"; +import { renderToReadableStream } from "react-dom/server"; +import { + type EntryContext, + type HandleErrorFunction, + ServerRouter, +} from "react-router"; + +async function handleRequest( + request: Request, + responseStatusCode: number, + responseHeaders: Headers, + routerContext: EntryContext +): Promise { + const userAgent = request.headers.get("user-agent"); + + const body = await renderToReadableStream( + , + { + signal: request.signal, + onError(error: unknown) { + responseStatusCode = 500; + console.error(error); + }, + } + ); + + if (userAgent && isbot(userAgent)) { + await body.allReady; + } + + responseHeaders.set("Content-Type", "text/html"); + + return new Response(Sentry.injectTraceMetaTags(body), { + headers: responseHeaders, + status: responseStatusCode, + }); +} + +export const handleError: HandleErrorFunction = (error, { request }) => { + // React Router also calls handleError for aborted requests, skip those + if (!request.signal.aborted) { + captureException(error, { + mechanism: { type: "react-router", handled: false }, + }); + console.error(error); + } +}; + +export default Sentry.wrapSentryHandleRequest(handleRequest); + +// Automatically instruments all server loaders, actions, middleware, +// and request handlers. +export const instrumentations = [Sentry.createSentryServerInstrumentation()]; +``` + +## Configure Client-Side Sentry + +The client setup is the same as on Node.js. Initialize Sentry in `app/entry.client.tsx` as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#configure-client-side-sentry). + +To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOnBuildEnd` hook as described in [Add Readable Stack Traces With Source Maps](/platforms/javascript/guides/react-router/manual-setup/#add-readable-stack-traces-with-source-maps-optional). + +## Deploy + +Build and deploy your app to Cloudflare Workers. You should start seeing errors and traces in Sentry, with request spans named after your React Router routes. From 2541e358b05378c16b4ab01ea2ba50c211cec64c Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Sun, 25 Oct 2026 20:09:19 +0000 Subject: [PATCH 2/9] docs(cloudflare): Align React Router on Cloudflare page with React Router guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the same step layout as the main React Router guide and show only the Sentry-specific changes to the server entry and Vite config instead of full template files. Co-Authored-By: Jan VamPeer Stöcklmair --- .../cloudflare/frameworks/react-router.mdx | 298 ++++++++++++------ 1 file changed, 208 insertions(+), 90 deletions(-) diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx index 44352944f9e669..aeb7780cf54681 100644 --- a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx @@ -5,19 +5,32 @@ description: "Learn how to instrument your React Router framework app on Cloudfl -This guide covers React Router apps in [framework mode](https://reactrouter.com/start/modes#framework) that you deploy to Cloudflare Workers with the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/). For Node.js deployments, see the [React Router guide](/platforms/javascript/guides/react-router/). For Shopify Oxygen, see [Hydrogen with React Router](/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router/). + + +This guide is for React Router apps in [framework mode](https://reactrouter.com/start/modes#framework) that you deploy to Cloudflare Workers with the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/). For Node.js deployments, see the [React Router guide](/platforms/javascript/guides/react-router/). For Shopify Oxygen, see [Hydrogen with React Router](/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router/). + + ## Prerequisites -Before you begin, make sure you have: +You need: - A Sentry [account](https://sentry.io/signup/) and [project](/product/projects/) -- A React Router app configured for Cloudflare Workers, for example one created with Cloudflare's [React Router guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/react-router/) +- A React Router app (version `7.15.0` or above) configured for Cloudflare Workers, for example one created with Cloudflare's [React Router guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/react-router/) + + + +## Install -## Install the SDKs + + + Install `@sentry/react-router` for the client and the React Router server entry, and `@sentry/cloudflare` for the Worker: + + + ```bash {tabTitle:npm} npm install @sentry/react-router @sentry/cloudflare ``` @@ -30,120 +43,225 @@ yarn add @sentry/react-router @sentry/cloudflare pnpm add @sentry/react-router @sentry/cloudflare ``` -## Configure Wrangler + + + + +## Configure + +Select which Sentry features you'd like to install in addition to Error Monitoring to get the corresponding installation and configuration instructions below. + + + + + +### Wrangler Configuration -## Instrument the Worker + + + + +### Client-Side Configuration + +Initialize Sentry in `app/entry.client.tsx`. If your app doesn't have this file yet, run `npx react-router reveal` to expose the entry files. -The Sentry Cloudflare Vite plugin wraps your Worker entry with `withSentry` at build time, so you don't need to change `workers/app.ts`. Add it to your Vite config after the Cloudflare and React Router plugins: + + -```typescript {filename:vite.config.ts} -import { cloudflare } from "@cloudflare/vite-plugin"; -import { reactRouter } from "@react-router/dev/vite"; -import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; -import { defineConfig } from "vite"; +```tsx {filename:app/entry.client.tsx} +import * as Sentry from "@sentry/react-router"; -export default defineConfig({ - plugins: [ - cloudflare({ viteEnvironment: { name: "ssr" } }), - reactRouter(), - sentryCloudflareVitePlugin(), +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + integrations: [ + // ___PRODUCT_OPTION_START___ performance + Sentry.reactRouterTracingIntegration(), + // ___PRODUCT_OPTION_END___ performance + // ___PRODUCT_OPTION_START___ session-replay + Sentry.replayIntegration(), + // ___PRODUCT_OPTION_END___ session-replay + // ___PRODUCT_OPTION_START___ user-feedback + Sentry.feedbackIntegration({ + // Additional SDK configuration goes in here, for example: + colorScheme: "system", + }), + // ___PRODUCT_OPTION_END___ user-feedback ], + // ___PRODUCT_OPTION_START___ performance + + // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing. + tracesSampleRate: 1.0, + + // Set `tracePropagationTargets` to declare which URL(s) should have trace propagation enabled + tracePropagationTargets: [/^\//, /^https:\/\/yourserver\.io\/api/], + // ___PRODUCT_OPTION_END___ performance + // ___PRODUCT_OPTION_START___ session-replay + + // Capture Replay for 10% of all sessions, + // plus 100% of sessions with an error + replaysSessionSampleRate: 0.1, + replaysOnErrorSampleRate: 1.0, + // ___PRODUCT_OPTION_END___ session-replay }); + +// ... rest of your client entry ``` -Then, create an `instrument.server.ts` file next to the Worker entry that `main` in your Wrangler configuration points to. For example, if `main` is `./workers/app.ts`, create `workers/instrument.server.ts`: + + + + + + +### Server-Side Configuration + +Add the Sentry Cloudflare Vite plugin after the Cloudflare and React Router plugins. It wraps your Worker entry with `withSentry` at build time, so you don't need to change `workers/app.ts`. + + + + +```typescript {diff} {filename:vite.config.ts} ++import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; + + export default defineConfig({ + plugins: [ + cloudflare({ viteEnvironment: { name: "ssr" } }), + reactRouter(), ++ sentryCloudflareVitePlugin(), + ], + }); +``` + + + + + + + +Then, create an `instrument.server.ts` file next to the Worker entry that `main` in your Wrangler configuration points to, for example `workers/instrument.server.ts`. + +For more on the plugin and its options, see the Vite plugin page. + + + ```typescript {filename:workers/instrument.server.ts} import { defineCloudflareOptions } from "@sentry/cloudflare"; export default defineCloudflareOptions({ dsn: "___PUBLIC_DSN___", + // ___PRODUCT_OPTION_START___ performance // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing. - // Learn more at - // https://docs.sentry.io/platforms/javascript/guides/cloudflare/configuration/options/#tracesSampleRate tracesSampleRate: 1.0, + // ___PRODUCT_OPTION_END___ performance }); ``` -For more on the plugin and its options, see the Vite plugin page. - -## Instrument the Server Entry - -Without React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation), the SDK only names a request after its route when React Router renders a document. Resource routes, and errors in loaders and actions, end up with a generic `GET` name. Export `instrumentations` from `app/entry.server.tsx` to create spans for all loaders, actions, middleware, and request handlers, named after their route. - -On Workers, import from `@sentry/react-router/cloudflare`. Wrap `handleRequest` with `wrapSentryHandleRequest`, pass the rendered stream through `injectTraceMetaTags` to connect server and client traces, and report errors from `handleError`: - -```tsx {filename:app/entry.server.tsx} -import { captureException } from "@sentry/cloudflare"; -import * as Sentry from "@sentry/react-router/cloudflare"; -import { isbot } from "isbot"; -import { renderToReadableStream } from "react-dom/server"; -import { - type EntryContext, - type HandleErrorFunction, - ServerRouter, -} from "react-router"; - -async function handleRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - routerContext: EntryContext -): Promise { - const userAgent = request.headers.get("user-agent"); - - const body = await renderToReadableStream( - , - { - signal: request.signal, - onError(error: unknown) { - responseStatusCode = 500; - console.error(error); - }, - } - ); - - if (userAgent && isbot(userAgent)) { - await body.allReady; - } - - responseHeaders.set("Content-Type", "text/html"); - - return new Response(Sentry.injectTraceMetaTags(body), { - headers: responseHeaders, - status: responseStatusCode, - }); -} - -export const handleError: HandleErrorFunction = (error, { request }) => { - // React Router also calls handleError for aborted requests, skip those - if (!request.signal.aborted) { - captureException(error, { - mechanism: { type: "react-router", handled: false }, - }); - console.error(error); - } -}; - -export default Sentry.wrapSentryHandleRequest(handleRequest); - -// Automatically instruments all server loaders, actions, middleware, -// and request handlers. -export const instrumentations = [Sentry.createSentryServerInstrumentation()]; + + + + + + +Next, update `app/entry.server.tsx`. Import from `@sentry/react-router/cloudflare`, wrap `handleRequest` with `wrapSentryHandleRequest`, pass the rendered stream through `injectTraceMetaTags` to connect server and client traces, and report errors from `handleError`. + +Exporting `instrumentations` uses React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation) to automatically create spans for all loaders, actions, middleware, and request handlers, named after their route. + + + + +```tsx {diff} {filename:app/entry.server.tsx} ++import { captureException } from "@sentry/cloudflare"; ++import * as Sentry from "@sentry/react-router/cloudflare"; ++import type { HandleErrorFunction } from "react-router"; + // ... your existing imports + +-export default async function handleRequest( ++async function handleRequest( + // ... your existing parameters + ) { + // ... your existing rendering logic + +- return new Response(body, { ++ return new Response(Sentry.injectTraceMetaTags(body), { + headers: responseHeaders, + status: responseStatusCode, + }); + } + ++export default Sentry.wrapSentryHandleRequest(handleRequest); ++ ++export const handleError: HandleErrorFunction = (error, { request }) => { ++ // React Router also calls handleError for aborted requests, skip those ++ if (!request.signal.aborted) { ++ captureException(error, { ++ mechanism: { type: "react-router", handled: false }, ++ }); ++ } ++}; ++ ++// Automatically instruments all server loaders, actions, middleware, ++// and request handlers. ++export const instrumentations = [Sentry.createSentryServerInstrumentation()]; ``` -## Configure Client-Side Sentry + + + + +### Add Readable Stack Traces With Source Maps (Optional) + +To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOnBuildEnd` hook as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#add-readable-stack-traces-with-source-maps-optional). + +### Control the Data You Send to Sentry (Optional) + + + +## Verify Your Setup + +Build and deploy your app to Cloudflare Workers, or run it locally with `wrangler dev`. Then throw a test error, for example from a loader or a button's click handler, and check your Sentry project. With tracing enabled, request spans are named after your React Router routes. + +### View Captured Data in Sentry + +Now, head over to your project on [Sentry.io](https://sentry.io/) to view the collected data (it takes a couple of moments for the data to appear). + + + +## Next Steps + +At this point, you should have integrated Sentry and should already be sending data to your Sentry project. + +Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: + +- Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup +- Learn how to [manually capture errors](/platforms/javascript/guides/cloudflare/usage/) +- Continue to [customize your configuration](/platforms/javascript/guides/cloudflare/configuration/) +- Make use of [Cloudflare-specific features](/platforms/javascript/guides/cloudflare/features/) -The client setup is the same as on Node.js. Initialize Sentry in `app/entry.client.tsx` as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#configure-client-side-sentry). + -To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOnBuildEnd` hook as described in [Add Readable Stack Traces With Source Maps](/platforms/javascript/guides/react-router/manual-setup/#add-readable-stack-traces-with-source-maps-optional). +- Check out setup instructions for other popular [frameworks on Cloudflare](/platforms/javascript/guides/cloudflare/frameworks/) +- Find various support topics in troubleshooting +- [Get support](https://www.sentry.help/en/) -## Deploy + -Build and deploy your app to Cloudflare Workers. You should start seeing errors and traces in Sentry, with request spans named after your React Router routes. + From 88691c1ca1b70e143effd6d2597b7292091614d9 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Sun, 25 Oct 2026 20:17:31 +0000 Subject: [PATCH 3/9] docs(cloudflare): Drop SplitLayout from the React Router on Cloudflare page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit master removed the SplitLayout components, so the page failed to prerender. Co-Authored-By: Jan Peer Stöcklmair --- .../cloudflare/frameworks/react-router.mdx | 49 ------------------- 1 file changed, 49 deletions(-) diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx index aeb7780cf54681..79bd66125e4608 100644 --- a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx @@ -22,15 +22,8 @@ You need: ## Install - - - - Install `@sentry/react-router` for the client and the React Router server entry, and `@sentry/cloudflare` for the Worker: - - - ```bash {tabTitle:npm} npm install @sentry/react-router @sentry/cloudflare ``` @@ -43,10 +36,6 @@ yarn add @sentry/react-router @sentry/cloudflare pnpm add @sentry/react-router @sentry/cloudflare ``` - - - - ## Configure Select which Sentry features you'd like to install in addition to Error Monitoring to get the corresponding installation and configuration instructions below. @@ -69,17 +58,10 @@ Select which Sentry features you'd like to install in addition to Error Monitori platform="javascript.cloudflare.splitlayout" /> - - - - ### Client-Side Configuration Initialize Sentry in `app/entry.client.tsx`. If your app doesn't have this file yet, run `npx react-router reveal` to expose the entry files. - - - ```tsx {filename:app/entry.client.tsx} import * as Sentry from "@sentry/react-router"; @@ -120,19 +102,10 @@ Sentry.init({ // ... rest of your client entry ``` - - - - - - ### Server-Side Configuration Add the Sentry Cloudflare Vite plugin after the Cloudflare and React Router plugins. It wraps your Worker entry with `withSentry` at build time, so you don't need to change `workers/app.ts`. - - - ```typescript {diff} {filename:vite.config.ts} +import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; @@ -145,19 +118,10 @@ Add the Sentry Cloudflare Vite plugin after the Cloudflare and React Router plug }); ``` - - - - - - Then, create an `instrument.server.ts` file next to the Worker entry that `main` in your Wrangler configuration points to, for example `workers/instrument.server.ts`. For more on the plugin and its options, see the Vite plugin page. - - - ```typescript {filename:workers/instrument.server.ts} import { defineCloudflareOptions } from "@sentry/cloudflare"; @@ -171,19 +135,10 @@ export default defineCloudflareOptions({ }); ``` - - - - - - Next, update `app/entry.server.tsx`. Import from `@sentry/react-router/cloudflare`, wrap `handleRequest` with `wrapSentryHandleRequest`, pass the rendered stream through `injectTraceMetaTags` to connect server and client traces, and report errors from `handleError`. Exporting `instrumentations` uses React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation) to automatically create spans for all loaders, actions, middleware, and request handlers, named after their route. - - - ```tsx {diff} {filename:app/entry.server.tsx} +import { captureException } from "@sentry/cloudflare"; +import * as Sentry from "@sentry/react-router/cloudflare"; @@ -219,10 +174,6 @@ Exporting `instrumentations` uses React Router's [instrumentation API](https://r +export const instrumentations = [Sentry.createSentryServerInstrumentation()]; ``` - - - - ### Add Readable Stack Traces With Source Maps (Optional) To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOnBuildEnd` hook as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#add-readable-stack-traces-with-source-maps-optional). From 82c180ceb38fd400dc423f0bcca9dbe5632b0d0e Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Sun, 25 Oct 2026 21:07:31 +0000 Subject: [PATCH 4/9] docs(cloudflare): List React Router on the Cloudflare page and tighten guide copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add React Router to the framework list on the Cloudflare guide, turn the server entry steps into a list that leads with why, and add a test button to the verify step like the other Cloudflare framework guides. Co-Authored-By: Jan VamPeer Stöcklmair --- .../cloudflare/frameworks/react-router.mdx | 24 +++++++++++++++---- .../javascript/guides/cloudflare/index.mdx | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx index 79bd66125e4608..460aa6edb9f036 100644 --- a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx @@ -60,7 +60,7 @@ Select which Sentry features you'd like to install in addition to Error Monitori ### Client-Side Configuration -Initialize Sentry in `app/entry.client.tsx`. If your app doesn't have this file yet, run `npx react-router reveal` to expose the entry files. +The client setup is the same as on Node.js. Initialize Sentry in `app/entry.client.tsx`. If your app doesn't have this file yet, run `npx react-router reveal` to expose the entry files. ```tsx {filename:app/entry.client.tsx} import * as Sentry from "@sentry/react-router"; @@ -135,9 +135,12 @@ export default defineCloudflareOptions({ }); ``` -Next, update `app/entry.server.tsx`. Import from `@sentry/react-router/cloudflare`, wrap `handleRequest` with `wrapSentryHandleRequest`, pass the rendered stream through `injectTraceMetaTags` to connect server and client traces, and report errors from `handleError`. +Next, update `app/entry.server.tsx` so Sentry captures server errors, names requests after their route, and connects server and client traces. On Workers, import from `@sentry/react-router/cloudflare`: -Exporting `instrumentations` uses React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation) to automatically create spans for all loaders, actions, middleware, and request handlers, named after their route. +- Wrap `handleRequest` with `wrapSentryHandleRequest`. +- Pass the rendered stream through `injectTraceMetaTags`. +- Report errors from `handleError`. +- Export `instrumentations` to create spans for all loaders, actions, middleware, and request handlers through React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation). ```tsx {diff} {filename:app/entry.server.tsx} +import { captureException } from "@sentry/cloudflare"; @@ -188,7 +191,20 @@ To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOn ## Verify Your Setup -Build and deploy your app to Cloudflare Workers, or run it locally with `wrangler dev`. Then throw a test error, for example from a loader or a button's click handler, and check your Sentry project. With tracing enabled, request spans are named after your React Router routes. +To verify that Sentry captures errors, add a test button to one of your pages: + +```tsx + +``` + +Run your app locally with `wrangler dev` or deploy it to Cloudflare Workers, click the button, and check your Sentry project for the error. With tracing enabled, Sentry names request spans after your React Router routes. ### View Captured Data in Sentry diff --git a/docs/platforms/javascript/guides/cloudflare/index.mdx b/docs/platforms/javascript/guides/cloudflare/index.mdx index 76049c2c545523..e2a0fc10ce5840 100644 --- a/docs/platforms/javascript/guides/cloudflare/index.mdx +++ b/docs/platforms/javascript/guides/cloudflare/index.mdx @@ -19,6 +19,7 @@ If you're using any of the listed frameworks, follow their specific setup instru - **[Hydrogen](/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router/)** - **[Next.js](/platforms/javascript/guides/cloudflare/frameworks/nextjs/)** - **[Nuxt](/platforms/javascript/guides/cloudflare/frameworks/nuxt/)** +- **[React Router](/platforms/javascript/guides/cloudflare/frameworks/react-router/)** - **[Remix](/platforms/javascript/guides/cloudflare/frameworks/remix/)** - **[SvelteKit](/platforms/javascript/guides/cloudflare/frameworks/sveltekit/)** - **[TanStack Start](/platforms/javascript/guides/cloudflare/frameworks/tanstack-start/)** From 8aad3dbbce90f71e20d1bc4711aaddb46cdf9daa Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Mon, 9 Nov 2026 11:41:00 +0000 Subject: [PATCH 5/9] docs(cloudflare): Apply the new quick start template to the React Router on Cloudflare page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the feature selector and product option markers so the snippets include every feature by default, add Send Logs and Send Application Metrics steps, and trim Verify and Next Steps like the other JavaScript quick starts. Use createSentryHandleRequest with renderToReadableStream from @sentry/react-router/cloudflare (SDK 11.10.0) for the server entry, and keep the wrapSentryHandleRequest path for custom handlers and older SDKs. Co-Authored-By: Jan Peer Stöcklmair --- .../cloudflare/frameworks/react-router.mdx | 207 +++++++++++------- 1 file changed, 128 insertions(+), 79 deletions(-) diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx index 460aa6edb9f036..955a67054243e9 100644 --- a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx @@ -18,7 +18,7 @@ You need: - A Sentry [account](https://sentry.io/signup/) and [project](/product/projects/) - A React Router app (version `7.15.0` or above) configured for Cloudflare Workers, for example one created with Cloudflare's [React Router guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/react-router/) - + ## Install @@ -38,73 +38,87 @@ pnpm add @sentry/react-router @sentry/cloudflare ## Configure -Select which Sentry features you'd like to install in addition to Error Monitoring to get the corresponding installation and configuration instructions below. - - +**Error Monitoring** starts working as soon as you configure Sentry. **Logs** and **Application Metrics** need no extra configuration, and you'll learn how to send them in steps [#3](#send-logs) and [#4](#send-application-metrics-). +This guide also enables **Tracing**, **Session Replay**, and **User Feedback**. -### Wrangler Configuration +### Expose Entry Point Files - +Sentry hooks into React Router's entry files (`entry.client.tsx` and `entry.server.tsx`). If your app doesn't have them yet, run this command to expose them: + +```bash +npx react-router reveal +``` + +### Configure Client-Side Sentry + +The client setup is the same as on Node.js. Initialize Sentry in your `entry.client.tsx` file. + +The snippet also turns on: -### Client-Side Configuration +- Tracing: via `tracesSampleRate` and `reactRouterTracingIntegration()` +- Session Replay: via `replayIntegration()`, sampled with `replaysSessionSampleRate` and `replaysOnErrorSampleRate` +- User Feedback: via `feedbackIntegration()` -The client setup is the same as on Node.js. Initialize Sentry in `app/entry.client.tsx`. If your app doesn't have this file yet, run `npx react-router reveal` to expose the entry files. +Don't need a feature? Remove its integration and options from the snippet. + +The `sentryOnError` handler integrates with React Router's [`onError` hook](https://reactrouter.com/how-to/error-reporting) to capture client-side errors. ```tsx {filename:app/entry.client.tsx} import * as Sentry from "@sentry/react-router"; +import { startTransition, StrictMode } from "react"; +import { hydrateRoot } from "react-dom/client"; +import { HydratedRouter } from "react-router/dom"; Sentry.init({ dsn: "___PUBLIC_DSN___", integrations: [ - // ___PRODUCT_OPTION_START___ performance + // Registers and configures the Tracing integration, + // which automatically instruments your application to monitor its + // performance, including custom React Router routing instrumentation Sentry.reactRouterTracingIntegration(), - // ___PRODUCT_OPTION_END___ performance - // ___PRODUCT_OPTION_START___ session-replay + // Registers the Replay integration, + // which automatically captures Session Replays Sentry.replayIntegration(), - // ___PRODUCT_OPTION_END___ session-replay - // ___PRODUCT_OPTION_START___ user-feedback + // Registers the User Feedback integration Sentry.feedbackIntegration({ // Additional SDK configuration goes in here, for example: colorScheme: "system", }), - // ___PRODUCT_OPTION_END___ user-feedback ], - // ___PRODUCT_OPTION_START___ performance - // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing. + // Enables Tracing. + // Set to 1.0 to capture 100% of spans for tracing. + // We recommend reducing this value in production. tracesSampleRate: 1.0, // Set `tracePropagationTargets` to declare which URL(s) should have trace propagation enabled tracePropagationTargets: [/^\//, /^https:\/\/yourserver\.io\/api/], - // ___PRODUCT_OPTION_END___ performance - // ___PRODUCT_OPTION_START___ session-replay - // Capture Replay for 10% of all sessions, - // plus 100% of sessions with an error + // Capture replays for 10% of all sessions, + // plus for 100% of sessions with an error + // Requires Sentry.replayIntegration() replaysSessionSampleRate: 0.1, replaysOnErrorSampleRate: 1.0, - // ___PRODUCT_OPTION_END___ session-replay }); -// ... rest of your client entry +startTransition(() => { + hydrateRoot( + document, + + + + ); +}); ``` -### Server-Side Configuration +### Add the Vite Plugin + +Add the Sentry Cloudflare Vite plugin to your `vite.config.ts`, after the Cloudflare and React Router plugins. It wraps your Worker entry with `withSentry` at build time, so you don't need to change `workers/app.ts`. It also instruments bundled dependencies such as database clients. Both behaviors are on by default. -Add the Sentry Cloudflare Vite plugin after the Cloudflare and React Router plugins. It wraps your Worker entry with `withSentry` at build time, so you don't need to change `workers/app.ts`. +To see its options and how to opt out of either behavior, see Vite Plugin. ```typescript {diff} {filename:vite.config.ts} +import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; @@ -118,34 +132,75 @@ Add the Sentry Cloudflare Vite plugin after the Cloudflare and React Router plug }); ``` -Then, create an `instrument.server.ts` file next to the Worker entry that `main` in your Wrangler configuration points to, for example `workers/instrument.server.ts`. +### Wrangler Configuration + + + +### Configure Server-Side Sentry + +Create an `instrument.server.ts` file next to the Worker entry that `main` in your Wrangler configuration points to, for example `workers/instrument.server.ts`. The plugin passes its default export to `withSentry`. + +The snippet also turns on: -For more on the plugin and its options, see the Vite plugin page. +- Tracing: via `tracesSampleRate` + +Don't need a feature? Remove its options from the snippet. ```typescript {filename:workers/instrument.server.ts} import { defineCloudflareOptions } from "@sentry/cloudflare"; -export default defineCloudflareOptions({ +export default defineCloudflareOptions((env) => ({ dsn: "___PUBLIC_DSN___", - // ___PRODUCT_OPTION_START___ performance - // Set tracesSampleRate to 1.0 to capture 100% of spans for tracing. + // Enables Tracing. + // Set to 1.0 to capture 100% of spans for tracing. + // We recommend reducing this value in production. tracesSampleRate: 1.0, - // ___PRODUCT_OPTION_END___ performance -}); +})); ``` -Next, update `app/entry.server.tsx` so Sentry captures server errors, names requests after their route, and connects server and client traces. On Workers, import from `@sentry/react-router/cloudflare`: +Next, replace the contents of `app/entry.server.tsx` so Sentry captures server errors, names requests after their route, and connects server and client traces. On Workers, import from `@sentry/react-router/cloudflare`: -- Wrap `handleRequest` with `wrapSentryHandleRequest`. -- Pass the rendered stream through `injectTraceMetaTags`. +- Replace your `handleRequest` function with `createSentryHandleRequest`, which renders with `renderToReadableStream` and injects the trace meta tags. - Report errors from `handleError`. - Export `instrumentations` to create spans for all loaders, actions, middleware, and request handlers through React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation). +```tsx {filename:app/entry.server.tsx} +import { captureException } from "@sentry/cloudflare"; +import * as Sentry from "@sentry/react-router/cloudflare"; +import { renderToReadableStream } from "react-dom/server"; +import { ServerRouter, type HandleErrorFunction } from "react-router"; + +export default Sentry.createSentryHandleRequest({ + ServerRouter, + renderToReadableStream, +}); + +export const handleError: HandleErrorFunction = (error, { request }) => { + // React Router also calls handleError for aborted requests, skip those + if (!request.signal.aborted) { + captureException(error, { + mechanism: { type: "react-router", handled: false }, + }); + } +}; + +// Automatically instruments all server loaders, actions, middleware, +// and request handlers. +export const instrumentations = [Sentry.createSentryServerInstrumentation()]; +``` + +On Cloudflare, `createSentryHandleRequest` needs SDK version `11.10.0` or above. If your app uses a nonce-based Content Security Policy, pass `getNonce` to it as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#configure-server-side-sentry). + + + +If you need custom rendering logic, or you're on SDK version `11.5.0` to `11.9.x`, keep your `handleRequest` function and add Sentry to it yourself. Wrap it with `wrapSentryHandleRequest` and pass the rendered stream through `injectTraceMetaTags`: + ```tsx {diff} {filename:app/entry.server.tsx} -+import { captureException } from "@sentry/cloudflare"; +import * as Sentry from "@sentry/react-router/cloudflare"; -+import type { HandleErrorFunction } from "react-router"; // ... your existing imports -export default async function handleRequest( @@ -162,36 +217,33 @@ Next, update `app/entry.server.tsx` so Sentry captures server errors, names requ } +export default Sentry.wrapSentryHandleRequest(handleRequest); -+ -+export const handleError: HandleErrorFunction = (error, { request }) => { -+ // React Router also calls handleError for aborted requests, skip those -+ if (!request.signal.aborted) { -+ captureException(error, { -+ mechanism: { type: "react-router", handled: false }, -+ }); -+ } -+}; -+ -+// Automatically instruments all server loaders, actions, middleware, -+// and request handlers. -+export const instrumentations = [Sentry.createSentryServerInstrumentation()]; ``` -### Add Readable Stack Traces With Source Maps (Optional) +Keep the `handleError` and `instrumentations` exports from the snippet above. -To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOnBuildEnd` hook as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#add-readable-stack-traces-with-source-maps-optional). + -### Control the Data You Send to Sentry (Optional) +### Add Readable Stack Traces With Source Maps - +To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOnBuildEnd` hook as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#add-readable-stack-traces-with-source-maps). + +### Control the Data You Send to Sentry + + + +## Send Logs + + + +If you're already logging with `console` or Consola, you can capture those logs with our console integrations. + +## Send Application Metrics + + ## Verify Your Setup -To verify that Sentry captures errors, add a test button to one of your pages: +To confirm that Sentry captures errors, add a test button to one of your pages: ```tsx ``` -Run your app locally with `wrangler dev` or deploy it to Cloudflare Workers, click the button, and check your Sentry project for the error. With tracing enabled, Sentry names request spans after your React Router routes. +Start your app locally or deploy it to Cloudflare Workers, then click the button. ### View Captured Data in Sentry -Now, head over to your project on [Sentry.io](https://sentry.io/) to view the collected data (it takes a couple of moments for the data to appear). +Now, head over to your project on [Sentry.io](https://sentry.io) to view the collected data (it takes a couple of moments for the data to appear). - + ## Next Steps -At this point, you should have integrated Sentry and should already be sending data to your Sentry project. - -Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +At this point, you should have integrated Sentry into your React Router app on Cloudflare Workers. Here's what to explore next: - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup -- Learn how to [manually capture errors](/platforms/javascript/guides/cloudflare/usage/) -- Continue to [customize your configuration](/platforms/javascript/guides/cloudflare/configuration/) -- Make use of [Cloudflare-specific features](/platforms/javascript/guides/cloudflare/features/) +- Set up tunneling to avoid ad blockers blocking Sentry events +- Set up Agent Tracing to monitor your AI systems @@ -231,4 +280,4 @@ Now's a good time to customize your setup and look into more advanced topics. Ou - + From ddb53330dedf31ec39e68ef6edbf673335b3f2e7 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Mon, 9 Nov 2026 12:14:59 +0000 Subject: [PATCH 6/9] docs(cloudflare): Shorten the Vite plugin step on the React Router on Cloudflare page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Jan Peer Stöcklmair --- .../javascript/guides/cloudflare/frameworks/react-router.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx index 955a67054243e9..950655f5af6a23 100644 --- a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx @@ -116,9 +116,7 @@ startTransition(() => { ### Add the Vite Plugin -Add the Sentry Cloudflare Vite plugin to your `vite.config.ts`, after the Cloudflare and React Router plugins. It wraps your Worker entry with `withSentry` at build time, so you don't need to change `workers/app.ts`. It also instruments bundled dependencies such as database clients. Both behaviors are on by default. - -To see its options and how to opt out of either behavior, see Vite Plugin. +Add the Sentry Cloudflare Vite plugin at the end of the `plugins` array in your `vite.config.ts`. To learn what it does and see its options, see Vite Plugin. ```typescript {diff} {filename:vite.config.ts} +import { sentryCloudflareVitePlugin } from "@sentry/cloudflare/vite"; From 910c142e446e068c16e9de97c3a9e8b7ed633f00 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Mon, 9 Nov 2026 12:16:05 +0000 Subject: [PATCH 7/9] docs(cloudflare): Shorten the instrument.server.ts step on the React Router on Cloudflare page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Jan Peer Stöcklmair --- .../javascript/guides/cloudflare/frameworks/react-router.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx index 950655f5af6a23..7ed4bef8873202 100644 --- a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx @@ -139,7 +139,7 @@ Add the Sentry Cloudflare Vite plugin at the end of the `plugins` array in your ### Configure Server-Side Sentry -Create an `instrument.server.ts` file next to the Worker entry that `main` in your Wrangler configuration points to, for example `workers/instrument.server.ts`. The plugin passes its default export to `withSentry`. +Create a `workers/instrument.server.ts` file to initialize Sentry on the server. The snippet also turns on: From d96ed19708e55b39b76b4ae1ed9e672ff94468ea Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Mon, 9 Nov 2026 12:34:19 +0000 Subject: [PATCH 8/9] docs(cloudflare): Trim the copy on the React Router on Cloudflare page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Jan Peer Stöcklmair --- .../cloudflare/frameworks/react-router.mdx | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx index 7ed4bef8873202..29f84d405395b9 100644 --- a/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx +++ b/docs/platforms/javascript/guides/cloudflare/frameworks/react-router.mdx @@ -7,7 +7,7 @@ description: "Learn how to instrument your React Router framework app on Cloudfl -This guide is for React Router apps in [framework mode](https://reactrouter.com/start/modes#framework) that you deploy to Cloudflare Workers with the [Cloudflare Vite plugin](https://developers.cloudflare.com/workers/vite-plugin/). For Node.js deployments, see the [React Router guide](/platforms/javascript/guides/react-router/). For Shopify Oxygen, see [Hydrogen with React Router](/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router/). +This guide is for React Router [framework mode](https://reactrouter.com/start/modes#framework) apps on Cloudflare Workers. For Node.js, see the [React Router guide](/platforms/javascript/guides/react-router/). For Shopify Oxygen, see [Hydrogen with React Router](/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router/). @@ -16,13 +16,13 @@ This guide is for React Router apps in [framework mode](https://reactrouter.com/ You need: - A Sentry [account](https://sentry.io/signup/) and [project](/product/projects/) -- A React Router app (version `7.15.0` or above) configured for Cloudflare Workers, for example one created with Cloudflare's [React Router guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/react-router/) +- A React Router app (version `7.15.0` or above) on Cloudflare Workers ([Cloudflare's setup guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/react-router/)) ## Install -Install `@sentry/react-router` for the client and the React Router server entry, and `@sentry/cloudflare` for the Worker: +Install the Sentry SDKs: ```bash {tabTitle:npm} npm install @sentry/react-router @sentry/cloudflare @@ -45,7 +45,7 @@ This guide also enables **Tracing**, **Session Replay**, and **User Feedback**. ### Expose Entry Point Files -Sentry hooks into React Router's entry files (`entry.client.tsx` and `entry.server.tsx`). If your app doesn't have them yet, run this command to expose them: +If your app doesn't have `entry.client.tsx` and `entry.server.tsx` yet, expose them: ```bash npx react-router reveal @@ -53,7 +53,7 @@ npx react-router reveal ### Configure Client-Side Sentry -The client setup is the same as on Node.js. Initialize Sentry in your `entry.client.tsx` file. +Initialize Sentry in `entry.client.tsx`. The snippet also turns on: @@ -63,8 +63,6 @@ The snippet also turns on: Don't need a feature? Remove its integration and options from the snippet. -The `sentryOnError` handler integrates with React Router's [`onError` hook](https://reactrouter.com/how-to/error-reporting) to capture client-side errors. - ```tsx {filename:app/entry.client.tsx} import * as Sentry from "@sentry/react-router"; import { startTransition, StrictMode } from "react"; @@ -108,6 +106,7 @@ startTransition(() => { hydrateRoot( document, + {/* Captures client-side errors */} ); @@ -160,11 +159,7 @@ export default defineCloudflareOptions((env) => ({ })); ``` -Next, replace the contents of `app/entry.server.tsx` so Sentry captures server errors, names requests after their route, and connects server and client traces. On Workers, import from `@sentry/react-router/cloudflare`: - -- Replace your `handleRequest` function with `createSentryHandleRequest`, which renders with `renderToReadableStream` and injects the trace meta tags. -- Report errors from `handleError`. -- Export `instrumentations` to create spans for all loaders, actions, middleware, and request handlers through React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation). +Next, replace the contents of `app/entry.server.tsx`. On Workers, import from `@sentry/react-router/cloudflare`: ```tsx {filename:app/entry.server.tsx} import { captureException } from "@sentry/cloudflare"; @@ -172,6 +167,7 @@ import * as Sentry from "@sentry/react-router/cloudflare"; import { renderToReadableStream } from "react-dom/server"; import { ServerRouter, type HandleErrorFunction } from "react-router"; +// Renders the app and connects server and client traces export default Sentry.createSentryHandleRequest({ ServerRouter, renderToReadableStream, @@ -191,11 +187,11 @@ export const handleError: HandleErrorFunction = (error, { request }) => { export const instrumentations = [Sentry.createSentryServerInstrumentation()]; ``` -On Cloudflare, `createSentryHandleRequest` needs SDK version `11.10.0` or above. If your app uses a nonce-based Content Security Policy, pass `getNonce` to it as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#configure-server-side-sentry). +`createSentryHandleRequest` needs SDK version `11.10.0` or above. For CSP nonces, pass [`getNonce`](/platforms/javascript/guides/react-router/manual-setup/#configure-server-side-sentry). -If you need custom rendering logic, or you're on SDK version `11.5.0` to `11.9.x`, keep your `handleRequest` function and add Sentry to it yourself. Wrap it with `wrapSentryHandleRequest` and pass the rendered stream through `injectTraceMetaTags`: +For custom rendering logic or SDK versions `11.5.0` to `11.9.x`, wrap your own `handleRequest` instead: ```tsx {diff} {filename:app/entry.server.tsx} +import * as Sentry from "@sentry/react-router/cloudflare"; @@ -217,13 +213,13 @@ If you need custom rendering logic, or you're on SDK version `11.5.0` to `11.9.x +export default Sentry.wrapSentryHandleRequest(handleRequest); ``` -Keep the `handleError` and `instrumentations` exports from the snippet above. +Keep the `handleError` and `instrumentations` exports from above. ### Add Readable Stack Traces With Source Maps -To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOnBuildEnd` hook as described in the [React Router guide](/platforms/javascript/guides/react-router/manual-setup/#add-readable-stack-traces-with-source-maps). +Follow the [React Router source maps setup](/platforms/javascript/guides/react-router/manual-setup/#add-readable-stack-traces-with-source-maps). ### Control the Data You Send to Sentry @@ -233,7 +229,7 @@ To upload source maps, add the `sentryReactRouter` Vite plugin and the `sentryOn -If you're already logging with `console` or Consola, you can capture those logs with our console integrations. +Already logging with `console` or Consola? Capture those logs with the console integrations. ## Send Application Metrics @@ -241,7 +237,7 @@ If you're already logging with `console` or Consola, you can capture those logs ## Verify Your Setup -To confirm that Sentry captures errors, add a test button to one of your pages: +Add a test button to one of your pages: ```tsx