Set up React RUM
@fusescope/browser-react connects a React application to the
browser SDK. It names views from your
React Router configuration and reports caught rendering errors to
Errors.
Before you start
Section titled “Before you start”Create a web application
and copy its public rum_pub_… key. Allow the origin your React application runs on.
Use React 18 or 19 and React Router 6.30.6+ or 7.18.5+ with BrowserRouter or
createBrowserRouter. The browser SDK must be 0.2.0-beta.1 or later.
npm install @fusescope/browser@next @fusescope/browser-react@nextKeep the React and React Router versions already used by your application. The
adapter uses them as peers. If your app has no router, you can use just
ErrorBoundary; importing it does not import React Router.
Name views from route patterns
Section titled “Name views from route patterns”Pass reactRouterRouteTemplate(routes) to the browser SDK’s routeTemplate
configuration, using the same route objects you give React Router. Call init()
before mounting the app so the initial view and page-load Web Vitals already carry
the correct pattern.
import { init } from '@fusescope/browser';import { ErrorBoundary } from '@fusescope/browser-react';import { reactRouterRouteTemplate } from '@fusescope/browser-react/react-router';import { createRoot } from 'react-dom/client';import { BrowserRouter, Link, type RouteObject, useLocation, useParams, useRoutes } from 'react-router-dom';
function Product() { const { productId } = useParams(); return <h1>Product: {productId}</h1>;}
function TestRenderError(): never { throw new Error('React RUM test render error');}
const routes: RouteObject[] = [ { path: '/', element: <h1>Shop</h1> }, { path: '/products/:productId', element: <Product /> }, { path: '/debug/render-error', element: <TestRenderError /> },];
init({ applicationId: '<your RUM application id>', publicKey: 'rum_pub_…', endpoint: 'https://fusescope.example.com', service: 'web-shop', environment: 'production', version: '<your app version>', routeTemplate: reactRouterRouteTemplate(routes),});
function Pages() { return useRoutes(routes);}
function App() { const location = useLocation(); return <> <nav> <Link to="/products/red-shoe">Red shoe</Link>{' '} <Link to="/products/blue-boot">Blue boot</Link>{' '} <Link to="/debug/render-error">Test render error</Link> </nav> <ErrorBoundary resetKeys={[location.pathname]} fallback={<p role="alert">This page could not be displayed.</p>}> <Pages /> </ErrorBoundary> </>;}
const root = document.getElementById('root');if (root) createRoot(root).render(<BrowserRouter><App /></BrowserRouter>);The two product URLs both use /products/:productId in FuseScope. Navigating from
one product to another still creates a new view; the pattern groups visits without
putting product identifiers into the route label. Nested routes, index routes,
pathless layouts, optional segments and splats use their declared patterns.
An unmatched path is named /*.
If the router uses a basename, pass the same value to both:
routeTemplate: reactRouterRouteTemplate(routes, '/shop')// Mount the app under <BrowserRouter basename="/shop">.Route patterns exclude the basename. Changing only a query string or fragment keeps the current view, as in the browser SDK. Hash and memory routers do not produce the pathname navigations this adapter tracks.
Catch rendering errors
Section titled “Catch rendering errors”ErrorBoundary renders its fallback when a descendant throws during rendering
or a lifecycle method. It calls the browser SDK’s addError(), producing an
exception with fusescope.rum.error.source=manual, the current route and session,
and a component stack in fusescope.rum.react.component_stack. URL query strings
and fragments are always removed from that component stack, which is limited to
the first 4,096 characters, even if general URL collection is enabled.
Pass resetKeys={[location.pathname]} in a component that reads useLocation()
to recover when the user navigates away from a failed page. Reset keys are compared
by value with Object.is. Alternatively, use a fallback render function to offer
a retry after the cause of the error has been resolved:
<ErrorBoundary resetKeys={[location.pathname]} fallback={({ reset }) => <div role="alert"> <p>This page could not be displayed.</p> <button type="button" onClick={reset}>Try again</button> </div>}> <Pages /></ErrorBoundary>The fallback function also receives error (an unknown value). A different React
key still resets the boundary by remounting it. A boundary does not catch failures in
its own fallback, event handlers, asynchronous callbacks, or server-side rendering.
Use the browser SDK’s addError() for handled errors outside rendering; unhandled
browser errors still use its automatic capture.
For data routers, place this boundary inside the route element you want to
protect. React Router’s errorElement handles loader/action failures separately;
report those through addError() in your own error UI if needed. The outer boundary
around RouterProvider does not intercept errors React Router has already caught.
Privacy and consent
Section titled “Privacy and consent”The adapter shares the browser SDK’s sampling, privacy settings and consent. With
requireConsent: true, neither views nor caught render errors are recorded until
setConsent(true). Initialize before mounting the router even when consent is
required. Collection starts on the route the user is visiting when consent arrives.
Route labels contain patterns, but URL attributes still contain paths. Continue to use privacy settings and the application’s server-side PII policy. Do not place personal information in error messages or route definitions.
Verify in FuseScope
Section titled “Verify in FuseScope”- Open
/products/red-shoe, then follow the link to/products/blue-boot. - In Frontend → your application → Views, find
/products/:productId. Both visits contribute to that route, rather than separate rows for the product IDs. - Follow Test render error. The fallback should appear while the navigation remains visible.
- In Errors, find
React RUM test render error. Open it and check its source is manual, with the route/debug/render-errorand a linked session. - Upload source maps for the same
versionyou pass toinit()to see the original stack. Remove the test route afterwards.
Use a sampled session, grant consent if required, and allow a few seconds for the browser SDK to export before refreshing FuseScope. Follow the general web troubleshooting steps if no data arrives.
The SDK repository also includes a runnable React sample. Its default server records OTLP locally; the sample README explains how to point it at your own FuseScope application.