Watchlog DocsWatchlog Docs
Home
Get Started
Integrations
Log Watchlist
Home
Get Started
Integrations
Log Watchlist
  • Watchlog
  • Get Started
  • Custom Events
  • APM
  • Real User Monitoring (RUM)
  • Kubernetes Cluster Monitoring
  • AI Traces Client Libraries Documentation
  • Browser Synthetic Tests

Real User Monitoring (RUM)

Access the RUM dashboard at https://app.watchlog.io/rum to see real-user traffic, Web Vitals, JavaScript errors, slow resources, and session activity across your applications.


React Icon React

Installation

npm i @watchlog/rum-react
# optional (for more precise Web Vitals collection)
npm i web-vitals

Usage (React Router v6)

// src/main.tsx (or src/index.tsx)
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter, Route } from 'react-router-dom'
import { RumProvider, WatchlogRoutes } from '@watchlog/rum-react'

import App from './App'
import User from './UserPage'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RumProvider
      config={{
        app: 'my-react-app',          // your application name (as shown in the dashboard)
        apiKey: '<API-Key>',          // copy from Watchlog panel
        environment: 'prod',          // e.g., 'prod' | 'staging' | 'dev'
        endpoint: 'https://api.watchlog.io/rum', // or your self-hosted endpoint
        // Sampling & capture options
        sampleRate: 0.1,              // 0.0–1.0 fraction of sessions to collect
        networkSampleRate: 0.1,       // sampling for fetch/XHR/resource
        enableWebVitals: true,        // capture LCP/INP/CLS/TTFB
        autoTrackInitialView: true,   // send a page_view on first render
        captureLongTasks: true,       // capture long tasks (main thread)
        captureFetch: true,           // instrument window.fetch
        captureXHR: true,             // instrument XMLHttpRequest
        // Optional privacy hook (redact, drop, enrich events)
        beforeSend: (ev) => {
          // Drop event by returning null
          // if (ev.type === 'resource') return null

          // Example: redact email-like strings from error messages
          if (ev.type === 'error' && typeof ev.data?.message === 'string') {
            ev.data.message = ev.data.message.replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+/gi, '[redacted]')
          }

          // Example: strip query strings from page URLs
          if (ev.context?.page?.url) {
            const u = new URL(ev.context.page.url)
            u.search = ''
            ev.context.page.url = u.toString()
          }
          return ev
        },
      }}
    >
      <BrowserRouter>
        {/* Wrap your routes so RUM can auto-track route changes */}
        <WatchlogRoutes>
          <Route path="/" element={<App />} />
          <Route path="/user/:id" element={<User />} />
        </WatchlogRoutes>
      </BrowserRouter>
    </RumProvider>
  </React.StrictMode>
)

Event Types Collected

RUM captures several event types out of the box:

  • page_view — Route/page navigations (SPA & traditional).
  • web_vital — LCP / INP / CLS / TTFB values, with attribution when available.
  • resource — Browser resource timings (duration, size, initiator type).
  • error — JavaScript errors with message, stack, fingerprint and top paths.
  • custom — Optional, user-defined events (e.g., business actions).

Example payloads

page_view

{
  "type": "page_view",
  "app": "my-react-app",
  "environment": "prod",
  "ts": "2025-08-21T15:00:00.000Z",
  "sessionId": "c8f...",
  "deviceId": "c24...",
  "context": {
    "page": { "url": "https://site.com/user/42", "path": "/user/42", "normalizedPath": "/user/:id", "title": "Profile" },
    "viewport": { "w": 1512, "h": 982, "dpr": 2 },
    "userAgent": "Mozilla/5.0 ...",
    "language": "en",
    "timezone": "Asia/Tehran"
  }
}

web_vital

{
  "type": "web_vital",
  "data": { "name": "LCP", "value": 1835.42 },
  "context": { "page": { "path": "/user/42" } }
}

resource

{
  "type": "resource",
  "data": { "name": "https://cdn.example.com/app.js", "duration": 342.1, "transferSize": 128764, "initiator": "script" },
  "context": { "page": { "path": "/dashboard" } }
}

error

{
  "type": "error",
  "data": { "message": "TypeError: Cannot read properties of undefined", "stack": "at ...", "fingerprint": "ab12cd34" },
  "context": { "page": { "path": "/checkout" } }
}

Note: You can intercept/modify any event in beforeSend. Return null to drop it entirely.

SPA Routing

If you use React Router v6, wrap routes with <WatchlogRoutes> so RUM detects client-side navigations. If you use another router or a custom setup, you can still trigger a page view manually by toggling autoTrackInitialView and using the SDK’s route-change helpers (exposed internally by WatchlogRoutes).

Configuration Reference

OptionTypeDefaultDescription
appstring—Application name shown in the dashboard.
apiKeystring—Copy from RUM → Your RUM Credentials in the panel.
endpointstring—Collector endpoint (cloud or self-hosted).
environmentstring"prod"Environment tag (e.g., prod/staging/dev).
sampleRatenumber (0.0–1.0)1.0Fraction of sessions to record.
networkSampleRatenumber (0.0–1.0)1.0Sampling for resource/fetch/xhr events.
enableWebVitalsbooleantrueCapture LCP/INP/CLS/TTFB.
autoTrackInitialViewbooleantrueSend first page_view on mount.
captureLongTasksbooleantrueCapture long tasks (>50ms on main thread).
captureFetchbooleantrueInstrument window.fetch.
captureXHRbooleantrueInstrument XMLHttpRequest.
beforeSend`(ev) => evnull`undefined

Privacy & Redaction

Use beforeSend to drop sensitive events or redact PII. Consider:

  • Strip query strings or hashes from URLs.
  • Remove email addresses, phone numbers, or form values from error messages.
  • Lower sampling for high-traffic pages to reduce data volume.

Troubleshooting

  • No data in the dashboard? Confirm endpoint, apiKey, and app match the panel values.
  • SPAs not tracking route changes? Ensure your routes are wrapped by <WatchlogRoutes>.
  • Web Vitals missing? Install web-vitals and keep enableWebVitals: true.
  • Browser blocks third-party scripts? Verify CORS and that your collector domain is reachable from clients.
  • Too much data? Lower sampleRate / networkSampleRate, or drop events via beforeSend.

Vue — Coming Soon

Vue SDK is in development. It will support automatic page views with Vue Router, Web Vitals, errors, resources, beforeSend, and TypeScript types. Stay tuned in Changelog for updates.

# Coming soon
npm i @watchlog/rum-vue

Next steps

  • Open the dashboard: https://app.watchlog.io/rum
  • Copy your Endpoint and API Key from Connect to RUM.
  • Deploy to your staging or production environment.
  • Explore: Overview → Web Vitals → Errors → Resources → Sessions.
Last Updated:: 8/22/25, 2:26 PM
Contributors: mohammad
Prev
APM
Next
Kubernetes Cluster Monitoring