Core Features

User Interactions

Click events and route changes — recorded as breadcrumbs so you can reconstruct what the user did before an error fired.

Click capture#

With captureClicks: true (default), Reliable installs a delegated click listener on document. Every click pushes a breadcrumb describing what was clicked — without sending a network request per click.

Each click breadcrumb includes:

  • A CSS selector for the clicked element (e.g. button.btn-primary, #checkout-submit)
  • The element's text content (truncated to 100 chars)
  • The element's tag name
  • Click coordinates (x, y) relative to the viewport

What a click breadcrumb looks like#

json
{
  "category": "click",
  "message": "button#checkout-submit \"Place order\"",
  "level": "info",
  "data": {
    "tag": "BUTTON",
    "selector": "button#checkout-submit",
    "text": "Place order",
    "x": 412,
    "y": 619
  },
  "timestamp": "2026-04-26T14:32:18.041Z"
}

With captureNavigation: true (default), Reliable patches history.pushState and history.replaceState, and listens for popstate. Every route change becomes a navigation breadcrumb and updates the SDK's current path state.

The current path is read by the error module when an error fires, so every error knows what route the user was on. The last 10 navigations are also attached to errors as router_history — so you can see the user's route trail leading up to the crash.

json
{
  "category": "navigation",
  "message": "/products/widget-42 → /cart",
  "level": "info",
  "data": {
    "from": "/products/widget-42",
    "to": "/cart",
    "type": "pushState"
  },
  "timestamp": "2026-04-26T14:32:17.802Z"
}

Routers without history.pushState#

The patching approach works for every modern router (React Router, Next.js App Router, Vue Router, TanStack Router) because they all use the History API under the hood. No adapter required.

For the rare case where you want explicit control — or your router uses a non-standard navigation primitive — see the useReliableRouter hook on the React → Router Adapters page.

Ignoring noisy elements#

If a particular element generates click noise (e.g. a draggable handle that fires hundreds of clicks per second), filter it out via beforeSend when the breadcrumb-bearing event is sent. Or scope your manual breadcrumbs more tightly:

typescript
// Tag the noisy area so you can filter it server-side
import { setTag } from '@reliableapp/frontend-core';

setTag('canvas_drag_active', 'true');
// ... interaction happens
setTag('canvas_drag_active', 'false');

Click data never leaves the breadcrumb buffer

Clicks aren't sent as standalone events — they only ride along when an error or other event flushes the breadcrumb buffer. This keeps payload volume tiny even on click-heavy apps.