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.

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:

  1. Initialize Sentry.reactRouterV6Instrumentation as your routing instrumentation and provide the functions it needs to enable performance tracing:

    • useEffect hook from react
    • useLocation and useNavigationType hooks from react-router-dom
    • createRoutesFromChildren and matchRoutes functions from react-router-dom or react-router packages.
  2. Wrap Routes using Sentry.withSentryReactRouterV6Routing to create a higher order component, which will enable Sentry to reach your router context, as in the example below:

Copied
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>,
);

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 (ex. /teams/:teamid/user/:userid instead of /teams/123/user/345), you must give the SDK access to the match path of the route render. This is as there is no static route config that the SDK can use in React Router v4/v5. There are two ways to accomplish this:

  1. Pass a Route Config Object

You can pass an array of route config objects as per react-router-config. to the instrumentation function call. You will also need to provide the matchPath function exported from the react-router-dom or react-router packages.

Copied
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>
  );
}
  1. Use Sentry Route component

Use the withSentryRouting higher order component to create a SentryRoute component that will update the match path on render.

Copied
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>
  );
}

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.

Copied
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:

Help improve this content
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").