-
-
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 6 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,21 @@ | ||||||
| --- | ||||||
| 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` | ||||||
| Apply the following setup steps based on your routing method and create a [custom error boundary](#usage-with-custom-error-boundaries) to make sure Sentry automatically captures rendering errors: | ||||||
|
|
||||||
| <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> | ||||||
| <TableOfContents | ||||||
| ignoreIds={["usage-with-custom-error-boundaries", "next-steps"]} | ||||||
| /> | ||||||
|
|
||||||
| ### Usage with `createBrowserRouter` or `createMemoryRouter` | ||||||
| ## Usage with `createBrowserRouter` or `createMemoryRouter` | ||||||
|
|
||||||
| 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: | ||||||
| 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: | ||||||
|
|
||||||
| <Alert level="warning" title="Note"> | ||||||
|
|
||||||
| `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 +51,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 +95,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 | ||||||
|
|
||||||
| <Alert> | ||||||
| Available in `@sentry/react` version `7.12.1` and above. | ||||||
| </Alert> | ||||||
| ## Usage With `useRoutes` Hook | ||||||
|
|
||||||
| 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. | ||||||
| _Available in `@sentry/react` version `7.12.1` and above._ | ||||||
|
|
||||||
| <Alert level="warning"> | ||||||
| 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. | ||||||
|
|
||||||
| `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,15 +150,17 @@ 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. | ||||||
| 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. | ||||||
|
|
||||||
| ### Custom Error Boundaries | ||||||
| ## Usage With Custom Error Boundaries | ||||||
|
||||||
| ## Usage With Custom Error Boundaries | |
| ## Set Up A Custom Error Boundary |
IMHO I would rephrase this like this, as everybody should follow this step?
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.
Updated this on v6 and v7 pages
Outdated
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.
Is this section helpful? What does it tell me? 😅 I should set this up anyhow to get all errors, I'd say?
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.
I mean this whole alert here!
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.
Removed it vor v6 and 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.
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
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.
I think for react router you need to add one, otherwise component-related errors get swallowed by the router itself.
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.
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!
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.
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 :) )
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,46 +1,27 @@ | ||
| --- | ||
| title: React Router v7 (library mode) | ||
| description: "Learn about Sentry's React Router v7 integration." | ||
| description: "Learn how to instrument your React Router v7 application with Sentry." | ||
| sidebar_order: 10 | ||
| --- | ||
|
|
||
|
|
||
| <Alert level="warning" title="Looking for framework mode?"> | ||
| - React Router v7 (framework mode) is currently in experimental Alpha, check out the docs [here](/platforms/javascript/guides/react-router/). | ||
| </Alert> | ||
|
|
||
| <Alert level="info"> | ||
| React Router v7 (library mode) support is included in the `@sentry/react` | ||
| package since version `8.42.0`. | ||
| </Alert> | ||
|
|
||
| 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` | ||
|
|
||
| <Alert level="warning"> | ||
|
|
||
| To ensure proper routing instrumentation, initialize Sentry by calling `Sentry.init` **before**: | ||
|
|
||
| - Wrapping your `<Routes />` component | ||
| - Using `useRoutes` | ||
| - Using `wrapCreateBrowserRouterV7` or `wrapCreateMemoryRouterV7` | ||
|
|
||
| <Alert level="info" title="Looking for framework mode?"> | ||
| React Router v7 (framework mode) is currently in experimental Alpha, check out | ||
| the docs [here](/platforms/javascript/guides/react-router/). | ||
| </Alert> | ||
| Apply the following setup steps based on your routing method and create a | ||
| [custom error boundary](#usage-with-custom-error-boundaries) to make sure Sentry | ||
| automatically captures rendering errors: | ||
|
|
||
| ### Usage with `createBrowserRouter` or `createMemoryRouter` | ||
|
|
||
| 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.wrapCreateBrowserRouterV7` or `Sentry.wrapCreateMemoryRouterV7` to wrap it with the instrumentation: | ||
| <TableOfContents | ||
| ignoreIds={["usage-with-custom-error-boundaries", "next-steps"]} | ||
| /> | ||
|
|
||
| <Alert level="warning" title="Note"> | ||
| ## Usage with `createBrowserRouter` or `createMemoryRouter` | ||
|
|
||
| `wrapCreateMemoryRouterV7` was introduced in SDK version 8.50.0. Prior to that version, we suggested using `wrapCreateBrowserRouterV7` with `createMemoryRouter`. If you are currently using `wrapCreateBrowserRouterV7` to wrap `createMemoryRouter`, it is recommended that you use `wrapCreateMemoryRouterV7` instead. | ||
| To instrument your React Router, update your `Sentry.browserTracingIntegration` to `Sentry.reactRouterV7BrowserTracingIntegration` 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: | ||
|
|
||
| You can instrument [`createHashRouter`](https://reactrouter.com/en/main/routers/create-hash-router) using the `wrapCreateBrowserRouterV7` function. | ||
|
|
||
| </Alert> | ||
| - Use `Sentry.wrapCreateBrowserRouterV7` for [`createBrowserRouter`](https://reactrouter.com/en/main/routers/create-browser-router) and [`createHashRouter`](https://reactrouter.com/en/main/routers/create-hash-router) | ||
| - Use `Sentry.wrapCreateMemoryRouterV7` 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"; | ||
|
|
@@ -76,9 +57,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.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: | ||
| If you're using the `<Routes />` component to define your routes, update your `Sentry.browserTracingIntegration` to `Sentry.reactRouterV7BrowserTracingIntegration` inside `Sentry.init` and provide the required React hooks and router functions. Then, 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. | ||
|
|
||
| ```javascript {3-11, 18-24, 29, 33-35} | ||
| import React from "react"; | ||
|
|
@@ -120,15 +101,14 @@ 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. | ||
|
|
||
| ### Usage With `useRoutes` Hook | ||
| 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. | ||
|
|
||
| If you specify your route definitions as an object to the [`useRoutes` hook](https://reactrouter.com/en/main/hooks/use-routes), use `Sentry.wrapUseRoutesV7` to create a patched `useRoutes` hook that instruments your routes with Sentry. | ||
| ## Usage With `useRoutes` Hook | ||
|
|
||
| <Alert level="warning"> | ||
| 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.reactRouterV7BrowserTracingIntegration` inside `Sentry.init` and provide the required React hooks and router functions. Then, use `Sentry.wrapUseRoutesV7` to create a patched `useRoutes` hook that instruments your routes with Sentry. | ||
|
|
||
| `wrapUseRoutesV7` 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 `wrapUseRoutesV7` 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> | ||
|
|
||
|
|
@@ -174,11 +154,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. | ||
| 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. | ||
|
|
||
| ### Custom Error Boundaries | ||
| ## Usage With Custom Error Boundaries | ||
|
||
|
|
||
| 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. | ||
| 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. | ||
|
|
||
| <Alert> | ||
|
||
| Note, that this only applies to render method and lifecycle errors since React | ||
|
|
@@ -227,7 +209,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!