The SDK patches history.pushState / history.replaceState and listens for
popstate, so every route change — and every back/forward — becomes a crumb.
That covers React Router, Next.js and TanStack Router with no configuration.
// nothing beyond the normal provider
<TraceItXProvider config={{ apiKey: 'txx_live_…' }}>
<App />
</TraceItXProvider>
// → breadcrumb: "/cart → /checkout?step=2"
The screen name is pathname + search. Same-URL transitions are dropped, and
the patch installs once per page no matter how many times the provider remounts
— React StrictMode and Fast Refresh are safe.
The hash-routing gap
Screen names are built from pathname and search only. A router that
navigates purely in the fragment — /#/checkout, React Router’s HashRouter —
never changes the tracked URL and emits no crumbs.
Switch that route tree to BrowserRouter, or your router’s equivalent
History-API mode, to get the trail automatically. Or keep the hash router and
emit the crumbs yourself from wherever you already observe route changes — a
kind: 'navigation' breadcrumb is treated exactly like an automatic one:
import { addBreadcrumb } from '@traceitx/react';
addBreadcrumb({ kind: 'navigation', message: `${from} → ${to}`, data: { from, to } });
Naming screens
Names travel in the report and are shown in triage. They do pass through the breadcrumb buffer’s redaction, so an obvious email or card number in a URL is caught — but redaction recognises shapes, not meaning, and an order id or an internal username sails through. Do not rely on it.
On the web the name comes from the URL, which means the rule is about your
routes: prefer /orders/:id shapes over paths that embed an email or a token
in the query string. If a route genuinely carries something sensitive, mark it
with redaction rules so it is scrubbed before capture.
What lands in the envelope
Navigation crumbs are entries in payload.breadcrumbs, the same timeline that
carries taps, console, network, lifecycle and error entries:
{
"t": 1755500000000,
"seq": 42,
"kind": "navigation",
"message": "/cart → /checkout",
"data": {
"from": "/cart",
"to": "/checkout"
}
}
t is the shared epoch-millisecond clock that also stamps the session replay,
so a receiver can align a crumb to a replay frame by direct comparison.
Caps and trimming behaviour are in Errors & limits.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| No crumbs on an app that clearly changes routes | Hash-based routing, or a router that re-renders without touching the History API. |
| Crumbs stop the moment the reporter opens | Expected. The trail is frozen when the report opens so the reporter’s own UI never pollutes the evidence. |
| The same screen appears twice in a row | It should not — A → A is suppressed. If you see it, the two URLs differ in search. |