React Router Integration
(Available in version 5.21.0 and above)
React Router support is included in the @sentry/react
package since version 5.21.0
.
Note
The React Router integration is designed to work with our Tracing SDK, @sentry/tracing
. Please see Getting Started with React Performance for more details on how to set up and install the SDK.
We support integrations for React Router 3, 4, 5, and 6.
React Router v6
(Available in version 7 and above)
To use React Router v6 with Sentry:
Initialize Sentry.reactRouterV6Instrumentation
as your routing instrumentation and provide the functions it needs to enable performance
- `useEffect` hook from `react`
- `useLocation` and `useNavigationType` hooks from `react-router-dom`
- `createRoutesFromChildren` and `matchRoutes` functions from `react-router-dom` or `react-router` packages.
Make sure Sentry.reactRouterV6Instrumentation
is initialized by your Sentry.init
call, before you wrap <Routes />
component or useRoutes
hook. Otherwise, the routing instrumentation may not work properly.
Usage with React Router 6.4 Data API
(Available in version 7.21.0 and above)
If you choose to create your router instance with createBrowserRouter
from the react-router-dom
package, you can use Sentry.wrapCreateBrowserRouter
to wrap it with the instrumentation:
import { createBrowserRouter } from 'react-router-dom';
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';
Sentry.init({
dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',
integrations: [
new BrowserTracing({
routingInstrumentation: Sentry.reactRouterV6Instrumentation(
React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
),
}),
],
tracesSampleRate: 1.0,
});
const sentryCreateBrowserRouter = Sentry.wrapCreateBrowserRouter(
createBrowserRouter
);
const router = sentryCreateBrowserRouter([
// ...
]);
Note
While createHashRouter
isn't supported by Sentry yet, you can instrument createMemoryRouter
using the wrapCreateBrowserRouter
function.
Usage With <Routes />
Component
If you use the <Routes />
component from react-router-dom
to define your routes, wrap Routes
using Sentry.withSentryReactRouterV6Routing
. This creates a higher order component, which will enable Sentry to reach your router context, as in the example below:
import React from 'react';
import ReactDOM from "react-dom";
import {
Routes,
BrowserRouter,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
} from "react-router-dom";
import * as Sentry from "@sentry/react";
import { BrowserTracing } from "@sentry/tracing";
Sentry.init({
integrations: [
new BrowserTracing({
routingInstrumentation: Sentry.reactRouterV6Instrumentation(
React.useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
),
}),
],
tracesSampleRate: 1.0,
});
const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes)
ReactDOM.render(
<BrowserRouter>
<SentryRoutes>
<Route path="/" element={<div>Home</div>} />
</SentryRoutes>
</BrowserRouter>,
);
Usage With useRoutes
Hook
(Available in version 7.12.1 and above)
If you specify your route definitions as an object to the useRoutes
hook, use Sentry.wrapUseRoutes
to create a patched useRoutes
hook that instruments your routes with Sentry.
wrapUseRoutes
should be called outside of a React component, as in the example below. It's also recommended that you assign the wrapped hook to a variable name starting with use
, as per the React documentation.
import {
createRoutesFromChildren,
matchRoutes,
useLocation,
useNavigationType,
useRoutes,
} from "react-router-dom";
import { wrapUseRoutes } from "@sentry/react";
import { useEffect } from "react";
import { BrowserTracing } from "@sentry/tracing";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
integrations: [
new BrowserTracing({
routingInstrumentation: Sentry.reactRouterV6Instrumentation(
useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
),
}),
],
tracesSampleRate: 1.0,
});
const useSentryRoutes = wrapUseRoutes(useRoutes);
function App() {
return useSentryRoutes([
// ...
]);
}
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.
React Router v4/v5
The React router instrumentation uses the React router library to create pageload/navigation
transactions and paramaterize transaction names. Make sure you use a Router
component combined with createBrowserHistory
(or equivalent).
Parameterized Transaction Names
To get parameterized transaction names (for example, /teams/:teamid/user/:userid
instead of /teams/123/user/345
), you must explicitly set the routes you want paramaterized. That's because there is no static route config that the SDK can use in React Router v4/v5.
We recommend you use the withSentryRouting
higher order component to create a SentryRoute
component that will update the match path on render.
import {Route, Router, Switch } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';
// Create Custom Sentry Route component
const SentryRoute = Sentry.withSentryRouting(Route);
const history = createBrowserHistory();
Sentry.init({
integrations: [
new BrowserTracing({
routingInstrumentation: Sentry.reactRouterV5Instrumentation(history),
}),
],
// We recommend adjusting this value in production, or using tracesSampler
// for finer control
tracesSampleRate: 1.0,
});
render() {
return (
<Router history={history}>
<Switch>
<SentryRoute path="/users/:userid" component={() => <div>UserId</div>} />
<SentryRoute path="/users" component={() => <div>Users</div>} />
<SentryRoute path="/" component={() => <div>Home</div>} />
</Switch>
</Router>
);
}
If you don't want to wrap individual routes, you can still specify parameterized routes manually by passing an array of route config objects, per react-router-config, to the instrumentation function call. You'll also need to provide the matchPath
function exported from the react-router-dom
or react-router
packages.
import { Route, Router, Switch, matchPath } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';
const history = createBrowserHistory();
// Array of Route Config Objects
// Make sure the order of the routes is correct. The longest url under the same parent should be placed first and in decreasing order.
const routes = [{ path: '/users/:userid' }, { path: '/users' }, { path: '/' }];
Sentry.init({
integrations: [
new BrowserTracing({
routingInstrumentation: Sentry.reactRouterV5Instrumentation(history, routes, matchPath),
}),
],
// We recommend adjusting this value in production, or using tracesSampler
// for finer control
tracesSampleRate: 1.0,
});
// In your App render:
render() {
return (
<Router history={history}>
<Switch>
<Route path="/users/:userid" component={() => <div>UserId</div>} />
<Route path="/users" component={() => <div>Users</div>} />
<Route path="/" component={() => <div>Home</div>} />
</Switch>
</Router>
);
}
React Router v3
To use the router integration, import and set a custom routing instrumentation and pass it the history, your routes and a match function. React Router v3 support is maintained for React Router >= 3.2.0 and < 4.0.0.
import * as Router from "react-router";
import * as Sentry from "@sentry/react";
import { BrowserTracing } from "@sentry/tracing";
// Routes looks like this:
const routes = (
<Route path="/">
<Route path="organizations/">
<Route path=":orgid" component={() => <div>OrgId</div>} />
<Route path=":orgid/v1/:teamid" component={() => <div>Team</div>} />
</Route>
</Route>
);
Sentry.init({
integrations: [
new BrowserTracing({
routingInstrumentation: Sentry.reactRouterV3Instrumentation(
Router.browserHistory,
// Must be Plain Routes.
Router.createRoutes(routes),
Router.match
),
}),
],
// We recommend adjusting this value in production, or using tracesSampler
// for finer control
tracesSampleRate: 1.0,
});
Next Steps:
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) to suggesting an update ("yeah, this would be better").
- Package:
- npm:@sentry/react
- Version:
- 7.45.0
- Repository:
- https://github.com/getsentry/sentry-javascript