React Router v7 (library mode)

Learn about Sentry's React Router v7 integration.

Update your Sentry.browserTracingIntegration to Sentry.reactRouterV7BrowserTracingIntegration and provide the required React hooks and router functions:

  • useEffect hook from react
  • useLocation and useNavigationType hooks from react-router
  • createRoutesFromChildren and matchRoutes functions from react-router

If you choose to create your router instance with createBrowserRouter or createMemoryRouter, you can use Sentry.wrapCreateBrowserRouterV7 or Sentry.wrapCreateMemoryRouterV7 to wrap it with the instrumentation:

Copied
import React from "react";
import { createBrowserRouter, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType, } from "react-router";
import * as Sentry from "@sentry/react"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [
Sentry.reactRouterV7BrowserTracingIntegration({ useEffect: React.useEffect, useLocation, useNavigationType, createRoutesFromChildren, matchRoutes, }),
], tracesSampleRate: 1.0, });

If you're using the <Routes /> component to define your routes, wrap Routes using Sentry.withSentryReactRouterV7Routing. This creates a higher order component, which will enable Sentry to reach your router context. You can also use Sentry.withSentryReactRouterV7Routing for Routes inside BrowserRouter. MemoryRouter, and HashRouter components:

Copied
import React from "react";
import ReactDOM from "react-dom";
import { Routes, Route, BrowserRouter, useLocation, useNavigationType, createRoutesFromChildren, matchRoutes, } from "react-router";
import * as Sentry from "@sentry/react"; Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [
Sentry.reactRouterV7BrowserTracingIntegration({ useEffect: React.useEffect, useLocation, useNavigationType, createRoutesFromChildren, matchRoutes, }),
], tracesSampleRate: 1.0, });
const SentryRoutes = Sentry.withSentryReactRouterV7Routing(Routes);
ReactDOM.render( <BrowserRouter>
<SentryRoutes> <Route path="/" element={<div>Home</div>} /> </SentryRoutes>
</BrowserRouter>, );

This is only needed at the top level of your app, rather than how v4/v5 required wrapping every <Route/> you wanted parametrized.

If you specify your route definitions as an object to the useRoutes hook, use Sentry.wrapUseRoutesV7 to create a patched useRoutes hook that instruments your routes with Sentry.

Copied
import React from "react";
import { createRoutesFromChildren, matchRoutes, useLocation, useNavigationType, useRoutes, } from "react-router"; import { wrapUseRoutes } from "@sentry/react";
Sentry.init({ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0", integrations: [
Sentry.reactRouterV7BrowserTracingIntegration({ useEffect: React.useEffect, useLocation, useNavigationType, createRoutesFromChildren, matchRoutes, }),
], tracesSampleRate: 1.0, });
const useSentryRoutes = wrapUseRoutesV7(useRoutes);
function App() {
return useSentryRoutes([ // your routes... ]);
} ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById("root"), );

Now, Sentry should generate pageload/navigation transactions with parameterized transaction names (for example, /teams/:teamid/user/:userid), where applicable. This is only needed at the top level of your app, rather than how v4/v5 required wrapping every <Route/> you wanted parametrized.

When using react-router, errors thrown inside route elements will only be re-thrown in development mode while using strict mode. In production, these errors won't be surfaced unless manually captured. If you don't have a custom error boundary in place, react-router will create a default one that "swallows" all errors.

To send errors to Sentry while using a custom error boundary, use the Sentry.captureException method:

Copied
// router setup
const sentryCreateBrowserRouter = wrapCreateBrowserRouterV7(createBrowserRouter);
const router = sentryCreateBrowserRouter([
  {
    path: "/",
    element: <YourLayout />,
    children: [
      {
        path: "",
        element: <Outlet />,
errorElement: <YourCustomRootErrorBoundary />,
children: [ // other routes ... ], }, ], }, ]); // error boundary import { useRouteError } from "react-router-dom"; import * as Sentry from "@sentry/react"; export function YourCustomRootErrorBoundary() { const error = useRouteError() as Error; React.useEffect(() => {
Sentry.captureException(error);
}, [error]); return ( <div> <h1>Ouch!</h1> </div> ); }

Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").