Introduction
If you haven't turned on tracing yet, start with turn on tracing in the quick start. This page covers the React-specific half: naming navigation spans after your router's routes. You can stop after the error reporting steps in the quick start and come back to this later. It isn't required to get errors into Flare.
On its own, @flareapp/js already traces page loads, client side navigations, and the fetch/XMLHttpRequest calls your page makes. It has no router though, so it names a navigation span after the raw URL it navigated to. @flareapp/react adds the route pattern, through a separate integration per router.
Adding your router's integration
Pick the router you use and add its integration. Both are subpath imports, not exports of @flareapp/react itself, so importing them from the root package will not work.
import { createRouter, RouterProvider } from '@tanstack/react-router';
import { traceTanStackRouter } from '@flareapp/react/tanstack-router';
import { routeTree } from './routeTree.gen';
const router = createRouter({ routeTree });
traceTanStackRouter(router);
export function App() {
return <RouterProvider router={router} />;
}
import { createBrowserRouter, RouterProvider } from 'react-router';
import { traceReactRouter } from '@flareapp/react/react-router';
import Home from './pages/Home';
import Product from './pages/Product';
const router = createBrowserRouter([
{ path: '/', Component: Home },
{ path: '/products/:id', Component: Product },
]);
traceReactRouter(router);
export function App() {
return <RouterProvider router={router} />;
}
traceReactRouter is built for a React Router v7 or v8 data router, one created with createBrowserRouter, createHashRouter, or createMemoryRouter. Pass it the router instance you get back from that call, before you render RouterProvider.
What the router integration adds
Without a router integration, a browser_navigation span only knows the raw URL it navigated to, for example /products/482. With the integration, the span also contains the matched route pattern, for example /products/:id, so every navigation to a product page groups together on the Pages table instead of becoming one entry for every product. When you open a single trace, you still see the URL. Flare uses the pattern to group pages, not to name the span.
Including the router base in the route pattern
The route pattern does not include the base of your router. An app served from /agent/certificates/ names its certificate route /:certificateId, not /agent/certificates/:certificateId. That works when one app reports to a Flare project. It does not work when several apps with different bases report to the same project: their routes land on the same rows of the Pages table, and you cannot tell them apart.
Both integrations take an options object as their second argument. Set includeRouterBase to put the base in front of the pattern:
import { createRouter } from '@tanstack/react-router';
import { traceTanStackRouter } from '@flareapp/react/tanstack-router';
import { routeTree } from './routeTree.gen';
const router = createRouter({ routeTree, basepath: '/agent/certificates' });
traceTanStackRouter(router, { includeRouterBase: true });
import { createBrowserRouter } from 'react-router';
import { traceReactRouter } from '@flareapp/react/react-router';
import Certificate from './pages/Certificate';
const router = createBrowserRouter([{ path: '/:certificateId', Component: Certificate }], {
basename: '/agent/certificates',
});
traceReactRouter(router, { includeRouterBase: true });
| Address bar | Route pattern by default | Route pattern with includeRouterBase |
|---|---|---|
/agent/certificates/abc |
/:certificateId |
/agent/certificates/:certificateId |
TanStack Router writes a param with a dollar sign, so its patterns are /$certificateId and /agent/certificates/$certificateId.
For TanStack Router the base is the basepath option. For React Router it is the basename option. A hash router has no page path option of its own, so its base is the path of the page that hosts it, followed by #. A createHashRouter served from /agent/certificates/ gives /agent/certificates/#/:certificateId. A trailing slash on the base is removed, so the pattern stays the same on every visit.
The option is off by default. Turning it on changes the route patterns of an app that has a base, so the Pages table shows new rows next to the old ones from before the change.
Stopping the router integration
Both traceTanStackRouter and traceReactRouter return a stop function:
const stopTracingNavigations = traceReactRouter(router);
// Later, for example when tearing down the router:
stopTracingNavigations();
Calling it unsubscribes from the router and stops opening navigation spans. You only need this if you tear down or replace the router instance while your app keeps running, for example in a test.
Read more
- Sampling: control how many traces get sent.
- Manual spans: time your own code inside a trace.
- Profiling introduction for React: time component mounts inside a trace.