Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 25 additions & 46 deletions docs/platforms/javascript/guides/react/features/react-router/v6.mdx
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
---

Copy link
Member

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:

Suggested change
You can instrument your React Router v6 setup with Sentry. Depending on how you use react-router, slightly different setups are needed:
<TableOfContents ignoreIds={["custom-error-boundary", "next-steps"]} />
Additionally, make sure to [Setup a Custom Error Boundary](#custom-error-boundary) to ensure rendering errors are captured to Sentry.

Copy link
Member

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

Copy link
Collaborator Author

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

Copy link
Member

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 😅

Copy link
Collaborator Author

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!

<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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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>

Expand Down Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Usage With Custom Error Boundaries
## Set Up A Custom Error Boundary

IMHO I would rephrase this like this, as everybody should follow this step?

Copy link
Collaborator Author

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


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
doesn't need error boundaries to handle errors in event handlers.
This only applies to render method and lifecycle errors since React doesn't
need error boundaries to handle errors in event handlers.
</Alert>
Copy link
Member

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?

Copy link
Member

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!

Copy link
Collaborator Author

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 👍


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

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

Copy link
Member

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.

Copy link
Member

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!

Copy link
Collaborator Author

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

Expand Down Expand Up @@ -226,7 +205,7 @@ export function YourCustomRootErrorBoundary() {

```

## Next Steps:
## Next Steps

- [Return to **Getting Started**](../../)
- [Return to the main integrations page](../)
72 changes: 27 additions & 45 deletions docs/platforms/javascript/guides/react/features/react-router/v7.mdx
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";
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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>

Expand Down Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above?


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>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, do we need this alert?

Note, that this only applies to render method and lifecycle errors since React
Expand Down Expand Up @@ -227,7 +209,7 @@ export function YourCustomRootErrorBoundary() {

```

## Next Steps:
## Next Steps

- [Return to **Getting Started**](../../)
- [Return to the main integrations page](../)