Browser RUM - ReactJS

Install

When using ReactJS, you typically control the base HTML (e.g., public/index.html in CRA, index.html in Vite, or your template in custom setups). Add the RUM SDK and initialise it early so navigation, resources, and errors are captured reliably.

Import JavaScript CDN

Add the script to the <head> of your index.html. The exact tag is also available on the Installation page of your Middleware account.

1<script
2  src="https://cdnjs.middleware.io/browser/libs/0.0.2/middleware-rum.min.js"
3  type="text/javascript"
4  crossorigin="anonymous"
5></script>

Order matters: keep this tag before your application bundle so the SDK can initialise first. If your app injects other scripts dynamically (analytics, feature flags), ensure Middleware’s script loads first to avoid race conditions.

Initialize the SDK

Place the init block after the CDN script in index.html (still inside <head> or just before </body>), or inject it via your HTML template system.

1<script>
2  if (window.Middleware) {
3    Middleware.track({
4      projectName: "my-application",
5      serviceName: "mw-application",
6      accountKey: "your-account-token",
7      target: "https://<UID>.middleware.io",
8      env: "production",
9      // Optional: version tag for correlation & sourcemaps
10      defaultAttributes: { "app.version": "1.0.0" }
11      // See "Configuration Object" on the main RUM Getting Started page
12    });
13  }
14</script>

React SPA route changes (soft navigations):

React apps often change routes via the History API (no full reload). The SDK treats these URL changes as new views, so soft navigations are measured like page loads. If your router does not update the URL (e.g., a memory router in tests), switch to a URL-updating router so route transitions appear under view.url. This mirrors standard RUM handling for SPAs.

Privacy quick-start (Session Recording):

You can strengthen privacy at init so sensitive content is masked/excluded on the client before any data is sent:

1<script>
2  if (window.Middleware) {
3    Middleware.track({
4      /* your existing config */
5      recording: "1", // default: full session capture
6      recordingOptions: {
7        maskAllInputs: true,                 // mask inputs as ***
8        maskTextSelector: ".pii, [data-pii]",// mask likely-PII text
9        blockSelector: ".auth-widget, .payment-form" // exclude regions
10      }
11    });
12  }
13</script>

See Session Recording Privacy for the complete option matrix (blockClass, ignoreSelector, custom mask functions).

Gate initialisation on your CMP signal. If you separate consent for recording, you can disable it while keeping analytics on.

1<script>
2  function hasAnalyticsConsent () {
3    return document.cookie.includes("consent_analytics=true");
4  }
5  if (hasAnalyticsConsent() && window.Middleware) {
6    Middleware.track({
7      /* your existing config */
8      // If the user declined recording:
9      // recording: "0"
10    });
11  }
12</script>

This follows common industry guidance without changing your SDK usage.

Add User Information

Add user attributes after the SDK is initialised—typically after login or when identity becomes available. In React, a simple useEffect in your auth boundary or app shell works well:

1import { useEffect } from "react";
2
3export default function App() {
4  useEffect(() => {
5    if (window.Middleware) {
6      window.Middleware.setAttributes({
7        name: "John Doe",
8        email: "[email protected]",
9        user_type: "admin" // arbitrary key-value pairs
10      });
11    }
12  }, []);
13
14  return /* your app */;
15}

You can call setAttributes any time the identity changes (e.g., user switches account). Keep PII minimised and rely on selectors/masking for sensitive UI regions.

Add Custom Logs

Use SDK helpers from anywhere in your React app—component effects, error boundaries, or service utilities:

1if (window.Middleware) {
2  Middleware.error("Your error message");
3  Middleware.error(new Error("Your error message"));
4  Middleware.info("info message");
5  Middleware.warn("warn message");
6  Middleware.debug("debug message");
7}

Once configured, data lands on the RUM Dashboard within minutes.

Distributed Tracing

Correlate frontend views/resources with backend traces, and open Session Replay from traces when recording is enabled. Make sure a Middleware APM Agent is installed in your backend.

Modify Middleware script

Add tracing config to your RUM init. tracePropagationTargets must be RegExp that match the hosts you call from the browser; tracePropagationFormat controls header style ("b3" default, "w3c" optional).

1<script>
2  if (window.Middleware) {
3    Middleware.track({
4      projectName: "mw-application",
5      serviceName: "my-application",
6      accountKey: "<account-key>",
7      target: "https://<UID>.middleware.io",
8      env: "production",
9      tracePropagationTargets: [/localhost:3000/i, /api\.domain\.com/i],
10      tracePropagationFormat: "b3" // or "w3c"
11      // ...other options
12    });
13  }
14</script>

Some backends require enabling the matching propagators (e.g., OTEL_PROPAGATORS=b3). Check your APM language page. The underlying concept mirrors how other RUM tools document SPA/route + tracing correlation.

What gets collected (at a glance)

RUM automatically captures Views (page loads & URL-based route changes), Resources (XHR/fetch, images, CSS/JS with timings), Errors (runtime), Long Tasks (>50 ms main-thread blocks), and Click actions. All events are tied to a Session (session.id) with device/geo/environment attributes for filtering. See the Browser Data Models page for full attribute lists.

Core Web Vitals (React focus)

Use Google’s Core Web Vitals to track real UX quality. Recommended “good” thresholds: LCP ≤ 2.5 s, CLS ≤ 0.1, INP ≤ 200 ms. Pair poor vitals with Session Replay to see what the user experienced; filter by view.url to find slow routes.

Troubleshooting (React specifics)

Nothing shows up (SPA):

Ensure your router updates the browser URL (e.g., BrowserRouter / HashRouter). Memory-only routers won’t create URL changes, so new views won’t be emitted. This aligns with how RUM tools detect soft navigations.

Minified stack traces in React errors: Upload source maps and set "app.version" in defaultAttributes to match your build. Then correlate errors to releases on the dashboard. (See Error Debugging page on your docs for CLI/webpack/Next.js options.)

CSP / corporate network blocks: Allow the SDK script host in script-src and your ingest target in connect-src. Example:

1Content-Security-Policy:
2  default-src 'self';
3  script-src 'self' https://cdnjs.middleware.io 'unsafe-inline';
4  connect-src 'self' https://<UID>.middleware.io;
5  img-src 'self' data:;
6  style-src 'self' 'unsafe-inline';

Re-validate CSP after SDK/CDN upgrades; corporate ad-blockers may also block replay endpoints.

Unhandled promise rejection on refresh:

Harmless if an in-flight API call is cancelled during reload; it doesn’t affect the RUM Browser SDK.

Need assistance or want to learn more about Middleware? Contact our support team at [email protected] or join our Slack channel.