React real user monitoring
Osuite Real User Monitoring runs in any browser application through the @osuite/rum package. In a plain React app — built with Vite or Create React App — you initialize the SDK once at your entry point and wrap your tree in the React error boundary from @osuite/rum/react. That gives you page-load and route-change spans, uncaught error capture, session replay, and end-to-end trace correlation with your backend, with strict privacy masking on by default.
Prerequisites
Section titled “Prerequisites”- A React 18 or newer app bundled with Vite or Create React App.
- An Osuite ingest token from Settings → API Keys.
- Your ingest region (
ingest.<region>.osuite.io).
Install
Section titled “Install”npm install @osuite/rum# orpnpm add @osuite/rumReact is declared as an optional peer dependency, so importing the error boundary from @osuite/rum/react needs no extra install. The baseline bundle does not pull React in.
Initialize the SDK
Section titled “Initialize the SDK”-
Call
osuite.initat your entry pointInitialize the SDK at the top of your app’s entry module, before React renders. A plain React entry runs only in the browser, so a module-scope call is safe here — no server-side guard is needed.
src/main.tsx import React from 'react';import ReactDOM from 'react-dom/client';import { osuite } from '@osuite/rum';import { OsuiteErrorBoundary } from '@osuite/rum/react';import App from './App';osuite.init({apiKey: import.meta.env.VITE_OSUITE_INGEST_TOKEN,endpoint: 'https://ingest.<region>.osuite.io',apiEndpoint: 'https://api.<region>.osuite.io',service: {name: 'frontend-web',version: import.meta.env.VITE_BUILD_SHA ?? 'dev',environment: import.meta.env.MODE,},});ReactDOM.createRoot(document.getElementById('root')!).render(<React.StrictMode><OsuiteErrorBoundary fallback={<p>Something went wrong.</p>}><App /></OsuiteErrorBoundary></React.StrictMode>,); -
Set the environment variables
endpointis the OTLP host the SDK posts traces and logs to;apiEndpointis the control-plane host used for session-replay uploads. They are different hosts — copy both from the values above and substitute your region. The ingest token is public (it ships in your JavaScript bundle and is rate-limited per key), so expose it through your bundler’s public env prefix:.env VITE_OSUITE_INGEST_TOKEN=<your-ingest-token>VITE_BUILD_SHA=dev -
Run the app
Start your dev server or serve a production build. Load a page and click around to generate telemetry.
That single call is enough to get page-load spans, fetch and XHR spans, click spans, error logs, and full session replay flowing. Every option beyond apiKey / endpoint / apiEndpoint / service is documented in the SDK reference.
Router integration
Section titled “Router integration”Client-side route changes are captured automatically. The SDK’s navigation tracker patches the History API (pushState, replaceState, popstate), so any router built on it — React Router’s BrowserRouter, TanStack Router, and similar — emits a route_change span per navigation with no extra wiring. Each span adopts the fetch and XHR calls fired during the transition and settles when the DOM is quiet, giving you the true settling time of every page transition.
Catch render errors
Section titled “Catch render errors”OsuiteErrorBoundary — imported from @osuite/rum/react in the entry file above — catches React render crashes, reports them as browser.react_error logs with a react.component_stack attribute, and triggers a sampling upgrade so the buffered context around the crash exports. Place it high in your tree, and add an onError callback if you need a side effect:
<OsuiteErrorBoundary fallback={<ErrorPage />} onError={(err, info) => {/* optional side-effect */}}> <App /></OsuiteErrorBoundary>Runtime errors, unhandled Promise rejections, and failed resource loads are captured by default without the boundary. See Frontend errors for every error source and manual capture.
Identify users
Section titled “Identify users”Once you know who is signed in, attach the user identity so sessions, errors, and replays are attributable. Clear it on sign-out. Either call rotates the session so a logged-in session is never conflated with the pre-login one:
import { osuite } from '@osuite/rum';
osuite.setUser({ id: 'u_123', plan: 'pro' });
osuite.clearUser();Do not pass email, phone, or other PII in id or extra — the SDK does not inspect these values. The full public API, including captureException, addSpanAttributes, and flush, is in the SDK reference.
Verify in Osuite
Section titled “Verify in Osuite”What you should see
Load a page and click around, then open RUM. Your session appears within a minute under the frontend-web service, with page-load and route-change spans and a session replay attached. Trigger a handled error with osuite.captureException and confirm it lands in the frontend error list, linked to the session that produced it.
Troubleshooting
Section titled “Troubleshooting”No data in Osuite after a few minutes? Work through these checks.
- Init ran — confirm
osuite.initexecutes before render and only once. Setdebug: true(see thedebugoption) to print init steps, sampling decisions, and transport failures toconsole.debug. - Network — open the browser Network tab and confirm
POSTrequests to${endpoint}/v1/tracesand${endpoint}/v1/logsare succeeding. A404means the ingest token is wrong or rotated — ingest matches the token at the edge, so an unrecognised token fails route matching instead of returning401/403. A CORS or connection error meansendpointis misconfigured. - Endpoint — confirm
endpointandapiEndpointpoint at the right region and are distinct hosts. Replay uploads useapiEndpoint, notendpoint. - No backend correlation — trace headers are same-origin only by default. If your API is on another origin, add it to the propagation allowlist.
Still stuck? Ask the Investigation Agent or contact support.
Next steps
Section titled “Next steps”- Session replay — masking, privacy classes, and upload behavior
- Frontend errors — error sources, event names, and manual capture
- Sampling — lower cost as traffic grows while keeping broken sessions
- SDK reference — every configuration option and the full public API