-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
docs(js): streamline React Router v6 and v7 documentation #13138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a8ed4d4
8584284
a5ff0ca
8d509ae
3c4f6b5
4c68e87
0417ac9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,41 +1,19 @@ | ||
| --- | ||
| title: React Router v6 | ||
| description: "Learn about Sentry's React Router v6 integration." | ||
| description: "Learn how to instrument your React Router v6 application with Sentry." | ||
| sidebar_order: 20 | ||
| --- | ||
|
|
||
| <Alert> | ||
| - React Router v6 support is included in the `@sentry/react` package since | ||
| version `7`. | ||
| </Alert> | ||
|
|
||
| Update your `Sentry.browserTracingIntegration` to `Sentry.reactRouterV6BrowserTracingIntegration` and provide the required React hooks and router functions: | ||
|
|
||
| - `useEffect` hook from `react` | ||
| - `useLocation` and `useNavigationType` hooks from `react-router-dom` or `react-router` | ||
| - `createRoutesFromChildren` and `matchRoutes` functions from `react-router-dom` or `react-router` | ||
|
|
||
| <Alert level="warning"> | ||
|
|
||
| To ensure proper routing instrumentation, initialize Sentry by calling `Sentry.init` **before**: | ||
|
|
||
| - Wrapping your `<Routes />` component | ||
| - Using `useRoutes` | ||
| - Using `wrapCreateBrowserRouterV6` or `wrapCreateMemoryRouterV6` | ||
|
|
||
| </Alert> | ||
| Apply the following setup steps based on your routing method and create a [custom error boundary](#set-up-a-custom-error-boundary) to make sure Sentry automatically captures rendering errors: | ||
|
|
||
| ### Usage with `createBrowserRouter` or `createMemoryRouter` | ||
| <TableOfContents ignoreIds={["set-up-a-custom-error-boundary", "next-steps"]} /> | ||
|
|
||
| If you choose to create your router instance with [`createBrowserRouter`](https://reactrouter.com/en/main/routers/create-browser-router) or [`createMemoryRouter`](https://reactrouter.com/en/main/routers/create-memory-router), you can use `Sentry.wrapCreateBrowserRouterV6` or `Sentry.wrapCreateMemoryRouterV6` to wrap it with the instrumentation: | ||
| ## Usage with `createBrowserRouter` or `createMemoryRouter` | ||
|
|
||
| <Alert level="warning" title="Note"> | ||
| To instrument your React Router, update your `Sentry.browserTracingIntegration` to `Sentry.reactRouterV6BrowserTracingIntegration` within `Sentry.init` and provide the required React hooks and router functions. Then, wrap the router instance created by `createBrowserRouter` or `createMemoryRouter` with one of the following functions: | ||
|
|
||
| `wrapCreateMemoryRouterV6` was introduced in SDK version 8.50.0. Prior to that version, we suggested using `wrapCreateBrowserRouterV6` with `createMemoryRouter`. If you are currently using `wrapCreateBrowserRouterV6` to wrap `createMemoryRouter`, it is recommended that you use `wrapCreateMemoryRouterV6` instead. | ||
|
|
||
| You can instrument [`createHashRouter`](https://reactrouter.com/en/main/routers/create-hash-router) using the `wrapCreateBrowserRouterV6` function. | ||
|
|
||
| </Alert> | ||
| - Use `Sentry.wrapCreateBrowserRouterV6` for [`createBrowserRouter`](https://reactrouter.com/en/main/routers/create-browser-router) and [`createHashRouter`](https://reactrouter.com/en/main/routers/create-hash-router) | ||
| - Use `Sentry.wrapCreateMemoryRouterV6` for [`createMemoryRouter`](https://reactrouter.com/en/main/routers/create-memory-router) (introduced in SDK version `8.50.0`) | ||
|
|
||
| ```javascript {2-8, 15-21, 26-33} | ||
| import React from "react"; | ||
|
|
@@ -71,9 +49,9 @@ const router = sentryCreateBrowserRouter([ | |
| ]); | ||
| ``` | ||
|
|
||
| ### Usage With `<Routes />` Component | ||
| ## Usage With `<Routes />` Component | ||
|
|
||
| If you're using the `<Routes />` component to define your routes, wrap [`Routes`](https://reactrouter.com/en/main/components/routes) using `Sentry.withSentryReactRouterV6Routing`. This creates a higher order component, which will enable Sentry to reach your router context. You can also use `Sentry.withSentryReactRouterV6Routing` for `Routes` inside `BrowserRouter`. `MemoryRouter`, and `HashRouter` components: | ||
| If you're using the `<Routes />` component to define your routes, update your `Sentry.browserTracingIntegration` to `Sentry.reactRouterV6BrowserTracingIntegration` inside `Sentry.init` and provide the required React hooks and router functions. Then, wrap `<Routes />` using `Sentry.withSentryReactRouterV6Routing`. This creates a higher order component, which will enable Sentry to reach your router context. You can also use `Sentry.withSentryReactRouterV6Routing` for routes inside `BrowserRouter`, `MemoryRouter`, and `HashRouter` components. | ||
|
|
||
| ```javascript {3-11, 18-24, 29, 33-35} | ||
| import React from "react"; | ||
|
|
@@ -115,19 +93,16 @@ ReactDOM.render( | |
| ); | ||
| ``` | ||
|
|
||
| This is only needed at the top level of your app, rather than how v4/v5 required wrapping every `<Route/>` you wanted parametrized. | ||
| This wrapper is only needed at the top level of your app, unlike React Router v4/v5, which required wrapping every `<Route />` you wanted parametrized. | ||
|
|
||
| ### Usage With `useRoutes` Hook | ||
| ## Usage With `useRoutes` Hook | ||
|
|
||
| <Alert> | ||
| Available in `@sentry/react` version `7.12.1` and above. | ||
| </Alert> | ||
| _Available in `@sentry/react` version `7.12.1` and above._ | ||
|
|
||
| If you specify your route definitions as an object to the [`useRoutes` hook](https://reactrouter.com/en/main/hooks/use-routes), use `Sentry.wrapUseRoutesV6` to create a patched `useRoutes` hook that instruments your routes with Sentry. | ||
| If you specify your route definitions as an object to the [`useRoutes` hook](https://reactrouter.com/en/main/hooks/use-routes), update your `Sentry.browserTracingIntegration` to `Sentry.reactRouterV6BrowserTracingIntegration` inside `Sentry.init` and provide the required React hooks and router functions. Then, use `Sentry.wrapUseRoutesV6` to create a patched `useRoutes` hook that instruments your routes with Sentry. | ||
|
|
||
| <Alert level="warning"> | ||
|
|
||
| `wrapUseRoutesV6` 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](https://reactjs.org/docs/hooks-custom.html#extracting-a-custom-hook). | ||
| <Alert level="warning" title="Important"> | ||
| Call `wrapUseRoutesV6` outside of a React component, as in the example below. We also recommend that you assign the wrapped hook to a variable starting with `use`, as per [React's documentation](https://react.dev/learn/reusing-logic-with-custom-hooks#hook-names-always-start-with-use). | ||
|
|
||
| </Alert> | ||
|
|
||
|
|
@@ -173,16 +148,13 @@ ReactDOM.render( | |
| ); | ||
| ``` | ||
|
|
||
| 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. | ||
|
|
||
| ### Custom Error Boundaries | ||
| 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, unlike React Router v4/v5, which 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`](https://react.dev/reference/react/StrictMode). 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. | ||
| ## Set Up a Custom Error Boundary | ||
|
|
||
| <Alert> | ||
| Note, that this only applies to render method and lifecycle errors since React | ||
| doesn't need error boundaries to handle errors in event handlers. | ||
| </Alert> | ||
| When using `react-router`, errors thrown inside route elements will only be re-thrown in **development mode** while using [`strict mode`](https://react.dev/reference/react/StrictMode).\ | ||
| In production, these errors won't surface unless captured manually. If you **don't** have a custom error boundary in place, `react-router` will create a default one that "swallows" all errors.\ | ||
| Hence, to capture these errors with Sentry in production, we strongly recommend to implement a custom error boundary. | ||
|
|
||
| To send errors to Sentry while using a custom error boundary, use the `Sentry.captureException` method: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not related to any change in this PR but generally: We should clarify here, because it is not clear to me: What If I am not using a custom error boundary, what should I do then? Should I add one to capture errors, or not? cc @lforst & @AbhiPrasad
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think for react router you need to add one, otherwise component-related errors get swallowed by the router itself.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, so let's reword this (can be a different PR as well) to make it clear you def should add this, not just if you're using a custom boundary!
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a sentence to the first paragraph in this section (v6 and v7 pages) -- hope this is what you meant (if not, let's chat later today @mydea :) ) |
||
|
|
||
|
|
@@ -226,7 +198,7 @@ export function YourCustomRootErrorBoundary() { | |
|
|
||
| ``` | ||
|
|
||
| ## Next Steps: | ||
| ## Next Steps | ||
|
|
||
| - [Return to **Getting Started**](../../) | ||
| - [Return to the main integrations page](../) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to lead with something like this:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and something similar for react-router v7 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mydea Good point! I updated the start of the page with an adapted version of your suggestion.
Sadly, the TableOfContents component does not work with our structure as it seems to be created to work with the SDK options pages, and our structure here is quite different -> I created an issue #13159 so we can consider upgrading the functionality of this component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be fixed here #13171 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the toc is now included - looks good!