diff --git a/docs/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router.mdx b/docs/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router.mdx
index 110d9bcf2460b..3ea06f20739ec 100644
--- a/docs/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router.mdx
+++ b/docs/platforms/javascript/guides/cloudflare/frameworks/hydrogen-react-router.mdx
@@ -467,7 +467,6 @@ Our next recommended steps for you are:
- Explore [practical guides](/guides) on what to monitor, log, track, and investigate after setup
- Learn how to manually capture errors
- Continue to customize your configuration
-- Make use of [React Router-specific features](/platforms/javascript/guides/react-router/features/)
- Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts
diff --git a/docs/platforms/javascript/guides/react-router/features/index.mdx b/docs/platforms/javascript/guides/react-router/features/index.mdx
deleted file mode 100644
index f9f320c96131d..0000000000000
--- a/docs/platforms/javascript/guides/react-router/features/index.mdx
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: React Router Features
-description: "Learn how Sentry's React Router SDK exposes features for first class integration with the framework."
-sidebar_order: 4
----
-
-
-
-This SDK is currently in **beta**. Beta features are still in progress and may have bugs. Please reach out on
-[GitHub](https://github.com/getsentry/sentry-javascript/issues/new/choose) if you have any feedback or concerns.
-
-
-
-The Sentry React Router SDK offers React Router-specific features for first class integration with the framework.
-
-
diff --git a/docs/platforms/javascript/guides/react-router/features/instrumentation-api.mdx b/docs/platforms/javascript/guides/react-router/features/instrumentation-api.mdx
deleted file mode 100644
index ccb9e1bcfaebe..0000000000000
--- a/docs/platforms/javascript/guides/react-router/features/instrumentation-api.mdx
+++ /dev/null
@@ -1,218 +0,0 @@
----
-title: Instrumentation API
-description: "Automatic tracing for loaders, actions, middleware, navigations, fetchers, lazy routes, and request handlers using React Router's instrumentation API."
-sidebar_order: 10
----
-
-React Router 7.15+ provides the stable [instrumentation API](https://reactrouter.com/how-to/instrumentation) used in this guide. React Router 7.9.5 introduced an earlier unstable version of the API with `unstable_*` names, so upgrade to 7.15+ before using the stable `instrumentations` examples below.
-
-The instrumentation API enables automatic span creation for loaders, actions, middleware, navigations, fetchers, lazy routes, and request handlers without the need for manual wrapper functions. Transaction names (for HTTP requests, pageloads, and navigations) use parameterized route patterns, such as `/users/:id`, and errors are automatically captured with proper context.
-
-## Server-Side Setup
-
-
-
-
-
-Export `instrumentations` from your `entry.server.tsx` to enable automatic server-side tracing.
-
-The `createSentryServerInstrumentation()` function creates spans for:
-
-- Request handlers (root HTTP server spans)
-- Loaders
-- Actions
-- Middleware
-- Lazy route loading
-
-
-
-
-```tsx {tabTitle:Server} {filename:entry.server.tsx}
-import * as Sentry from "@sentry/react-router";
-import { createReadableStreamFromReadable } from "@react-router/node";
-import { renderToPipeableStream } from "react-dom/server";
-import { ServerRouter } from "react-router";
-
-export default Sentry.createSentryHandleRequest({
- ServerRouter,
- renderToPipeableStream,
- createReadableStreamFromReadable,
-});
-
-export const handleError = Sentry.createSentryHandleError();
-
-// Enable automatic server-side instrumentation
-export const instrumentations = [
- Sentry.createSentryServerInstrumentation(),
-];
-```
-
-
-
-
-
-
-
-You can optionally configure error capture behavior:
-
-
-
-
-```typescript
-Sentry.createSentryServerInstrumentation({
- // Capture errors from loaders/actions automatically (default: true)
- captureErrors: true,
-});
-```
-
-
-
-
-
-## Client-Side Setup
-
-
-
-
-
-To enable the client-side instrumentation API, pass `useInstrumentationAPI: true` to `reactRouterTracingIntegration()` and provide the `clientInstrumentation` to `HydratedRouter`.
-
-The client instrumentation creates spans for:
-
-- Navigations (including back/forward)
-- Fetchers
-- Client loaders
-- Client actions
-- Client middleware
-- Lazy route loading
-
-
-
-`HydratedRouter` doesn't currently invoke client-side instrumentation hooks when running in Framework Mode. As a result, only client-side navigation spans are captured through the SDK's built-in instrumentation. The client-side setup shown here prepares your app for when React Router adds support for invoking these hooks.
-
-
-
-
-
-
-```tsx {tabTitle:Client} {filename: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";
-
-const tracing = Sentry.reactRouterTracingIntegration({
- useInstrumentationAPI: true,
-});
-
-Sentry.init({
- dsn: "___PUBLIC_DSN___",
- integrations: [tracing],
- tracesSampleRate: 1.0,
-});
-
-startTransition(() => {
- hydrateRoot(
- document,
-
-
-
- );
-});
-```
-
-
-
-
-
-## Migrating from Manual Wrappers
-
-If you're using `wrapServerLoader` and `wrapServerAction`, you can migrate to the instrumentation API. The SDK automatically detects when the instrumentation API is active and skips span creation in manual wrappers, so you can migrate incrementally without duplicate spans.
-
-
-
-
-
-**Before migrating** (manual wrappers):
-
-Without the instrumentation API, each loader and action needs to be wrapped individually.
-
-
-
-
-```tsx {filename:app/routes/users.$id.tsx}
-import * as Sentry from "@sentry/react-router";
-
-export const loader = Sentry.wrapServerLoader(
- { name: "Load User" },
- async ({ params }) => {
- const user = await getUser(params.id);
- return { user };
- }
-);
-
-export const action = Sentry.wrapServerAction(
- { name: "Update User" },
- async ({ request }) => {
- const formData = await request.formData();
- return updateUser(formData);
- }
-);
-```
-
-
-
-
-
-
-
-**After migrating** (instrumentation API):
-
-After adding the instrumentation export once in `entry.server.tsx`, all loaders and actions are traced automatically.
-
-
-
-
-```tsx {filename:app/routes/users.$id.tsx}
-// No Sentry imports or wrappers needed
-
-export async function loader({ params }) {
- const user = await getUser(params.id);
- return { user };
-}
-
-export async function action({ request }) {
- const formData = await request.formData();
- return updateUser(formData);
-}
-```
-
-
-
-
-
-## Troubleshooting
-
-
-
-If you're not seeing spans for your loaders and actions:
-
-1. Check that the React Router version is 7.15 or later for the stable `instrumentations` API. React Router 7.9.5 includes the earlier unstable API, which uses `unstable_*` names.
-2. Make sure `instrumentations` is exported from `entry.server.tsx`
-3. Verify `tracesSampleRate` is set in your server configuration
-
-
-
-
-
-If you're seeing duplicate spans after adding the instrumentation API:
-
-The SDK automatically detects when the instrumentation API is active and skips span creation in manual wrappers. If you're still seeing duplicates:
-
-1. Update to the latest SDK version
-2. Check that the instrumentation export is correctly configured
-3. Enable debug mode to verify the manual wrappers are being skipped—they log a message when the instrumentation API is active
-
-
diff --git a/docs/platforms/javascript/guides/react-router/manual-setup.mdx b/docs/platforms/javascript/guides/react-router/manual-setup.mdx
index 4b20938145a84..c8fc964477dbc 100644
--- a/docs/platforms/javascript/guides/react-router/manual-setup.mdx
+++ b/docs/platforms/javascript/guides/react-router/manual-setup.mdx
@@ -13,9 +13,9 @@ description: "Learn how to manually set up Sentry in your React Router v7 app an
Looking for automatic setup with `sentry init` or the React Router Framework
- Mode wizard? Follow the [React Router quickstart](/platforms/javascript/guides/react-router/)
- instead.
- Continue with this guide to set up Sentry manually.
+ Mode wizard? Follow the [React Router
+ quickstart](/platforms/javascript/guides/react-router/) instead. Continue with
+ this guide to set up Sentry manually.
@@ -198,49 +198,16 @@ startTransition(() => {
### Configure Server-Side Sentry
-
+
-Automatic server-side instrumentation is currently only supported on:
+Sentry's OpenTelemetry-based auto-instrumentation (loaded through `instrument.server.mjs`) is currently only supported on:
- **Node 20:** Version \<20.19
- **Node 22:** Version \<22.12
-If you're on a different version, you have two options:
+This restriction **doesn't** affect tracing for loaders, actions, middleware, and request handlers. Those are instrumented through React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation) (the `instrumentations` export shown below, React Router 7.15+), which works on all Node versions.
-1. **Recommended**: Use the stable Instrumentation API (React Router 7.15+) for automatic tracing without Node version restrictions. React Router 7.9.5 introduced an earlier unstable API with `unstable_*` names.
-2. **Alternative**: Use our manual server wrappers (shown below)
-
-For server loaders use `wrapServerLoader`:
-
-```ts
-import * as Sentry from "@sentry/react-router";
-
-export const loader = Sentry.wrapServerLoader(
- {
- name: "Load Some Data",
- description: "Loads some data from the db",
- },
- async ({ params }) => {
- // ... your loader logic
- }
-);
-```
-
-For server actions use `wrapServerAction`:
-
-```ts
-import * as Sentry from "@sentry/react-router";
-
-export const action = Sentry.wrapServerAction(
- {
- name: "Submit Form Data",
- description: "Processes form submission data",
- },
- async ({ request }) => {
- // ... your action logic
- }
-);
-```
+On unsupported Node versions, you'll only lose auto-instrumentation for lower-level operations such as outgoing HTTP requests and database queries.
@@ -298,7 +265,9 @@ Sentry.init({
-Next, replace the default `handleRequest` and `handleError` functions in your `entry.server.tsx` file with Sentry's wrapped versions:
+Next, replace the default `handleRequest` and `handleError` functions in your `entry.server.tsx` file with Sentry's wrapped versions, and export `instrumentations` to enable automatic tracing.
+
+Exporting `instrumentations` uses React Router's [instrumentation API](https://reactrouter.com/how-to/instrumentation) (React Router 7.15+) to automatically create spans for all loaders, actions, middleware, and request handlers — no need to wrap them individually.
@@ -322,6 +291,10 @@ Next, replace the default `handleRequest` and `handleError` functions in your `e
+ logErrors: false
+});
++// Automatically instruments all server loaders, actions, middleware,
++// and request handlers. Requires React Router 7.15+.
++export const instrumentations = [Sentry.createSentryServerInstrumentation()];
+
// ... rest of your server entry
```
diff --git a/redirects.js b/redirects.js
index 7d6184211d7ae..dc45e24574aa8 100644
--- a/redirects.js
+++ b/redirects.js
@@ -963,6 +963,10 @@ const userDocsRedirects = [
source: '/platforms/javascript/guides/aws-lambda/cjs-npm__v9.x/',
destination: '/platforms/javascript/guides/aws-lambda/install/cjs-npm__v9.x/',
},
+ {
+ source: '/platforms/javascript/guides/react-router/features/instrumentation-api/',
+ destination: '/platforms/javascript/guides/react-router/manual-setup/',
+ },
{
source: '/platforms/javascript/guides/nextjs/sourcemaps/uploading/',
destination: '/platforms/javascript/guides/nextjs/sourcemaps/',
@@ -1868,7 +1872,8 @@ const userDocsRedirects = [
},
{
source: '/product/insights/mobile-vitals/screen-loads/',
- destination: '/product/dashboards/sentry-dashboards/mobile/mobile-vitals/screen-loads/',
+ destination:
+ '/product/dashboards/sentry-dashboards/mobile/mobile-vitals/screen-loads/',
},
{
source: '/product/insights/mobile-vitals/:path*',