Browser RUM - Getting Started

This guide walks you through setting up Real User Monitoring (RUM) with JavaScript in the browser. These instructions can also be found on the Installation page in your Middleware account.

Install

If you are installing RUM in the browser with NextJS, skip to the NextJS section.

1 Create Application Reference

  • Go to Installation in your Middleware account.
  • In Real User Monitoring, select Create New Application.
  • Provide the Application name, Origin(s), and Trace Propagation Target(s) to whitelist.
    • Multiple origins can be listed as a comma-separated list.

2 Import JavaScript CDN

Add the following <script> tag to the <head> of your index.html. You can copy it directly from the Installation page after completing Step 1.

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>

Keep this script before your application code so the SDK can initialise early.

3 Initialize the SDK

Place the init code below the script from Step 2. The window.Middleware attribute is defined by the script below.

  • env and recording are optional.
  • recording: "1" (default) records the entire user session.
  • To track only browser traces and errors, set recording: "0". (If your account supports a mode that disables only video while keeping other signals, you may also see recording: "2" in the configuration table.)
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      defaultAttributes: {
10        "app.version": "1.0.0"
11      }
12      // See "Configuration Object" below for all options
13    });
14  }
15</script>

Single-Page Applications (Route Changes)

Single-page apps often update the URL via the History API (or hash) without a full reload. The SDK treats these soft navigations as new views, so route changes are measured like page loads. If your router does not update the URL on route change, enable URL updates so route transitions are captured as views (view.url will reflect the new route).

Privacy Quick-start (Masking & Exclusions)

You can harden privacy directly in the init using recordingOptions. These apply to Session Recording only and ensure sensitive content is masked or excluded client-side.

1<script>
2  if (window.Middleware) {
3    Middleware.track({
4      /* your existing config */
5      recording: "1",
6      recordingOptions: {
7        // Mask all form values (inputs, textareas, selects) as ***
8        maskAllInputs: true,
9        // Mask text inside elements that may contain PII
10        maskTextSelector: ".pii, [data-pii]",
11        // Exclude entire regions from recording (auth, payments, etc.)
12        blockSelector: ".auth-widget, .payment-form"
13      }
14    });
15  }
16</script>

For the complete option matrix (blockClass, ignoreSelector, custom mask functions, etc.) see Session Recording Privacy.

Gate initialisation on your consent signal (example uses a cookie flag). If you collect separate consent for session recording, keep analytics on and disable recording when needed.

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 session recording:
9      // recording: "0"
10    });
11  }
12</script>

This approach aligns with common RUM privacy guidance while keeping your SDK usage unchanged.

4 Add Application Version Information (Optional)

Set your application version so you can correlate errors and sessions to releases.

1if (window.Middleware) {
2  /* ... */
3  defaultAttributes: {
4    "app.version": "1.0.0"
5  }
6}

Tip: update the version dynamically during your release process. This helps with root-cause analysis and source map matching.

5 Add User Information (Optional)

Add user metadata as key–value pairs. You can also set or update attributes after initialisation with Middleware.setAttributes.

1if (window.Middleware) {
2  /* ... */
3  defaultAttributes: {
4    name: "John Doe",
5    email: "[email protected]",
6    user_type: "admin"
7  }
8}
9
10<script>
11  if (window.Middleware) {
12    Middleware.setAttributes({
13      name: "John Doe",
14      email: "[email protected]",
15      user_type: "admin"
16    });
17  }
18</script>

Call .setAttributes() after .track().

6 Add Custom Logs (Optional)

Use these helpers to log client-side issues and context:

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

Once RUM is configured, data appears on the RUM Dashboard within a few minutes.

What RUM Collects (At a Glance)

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

Core Web Vitals

Use Google’s Core Web Vitals to quantify UX quality and pair problem sessions with Session Replay for context.

  • Good thresholds (Google): LCP ≤ 2.5 s, CLS ≤ 0.1, INP ≤ 200 ms.
  • Filter by route (view.url) and environment to isolate slow templates.

Distributed Tracing

RUM tracing gives you end-to-end visibility into real user journeys. You can correlate front-end events with backend traces and view Session Replay alongside APM traces. You must have a Middleware APM Agent installed to use tracing.

Step 1: Modify Middleware script

Add tracePropagationTargets (array of RegExp that match your backend hosts) to your RUM config. You can also set tracePropagationFormat to "b3" (default) or "w3c" based on your backend’s expectation.

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      /* ... */
12    });
13  }
14</script>

Notes:

  • tracePropagationTargets omit http(s):// and should match the hosts you call from the browser.
  • tracePropagationFormat controls the wire headers that your backend APM will read.

Step 2: Modify APM SDK

Some language SDKs require OTEL_PROPAGATORS=b3 to accept propagated traces from the browser. See the table on this page to check if your SDK needs it.

Access RUM from Trace List

In APM → Trace List, open a trace to access its associated RUM Session Replay (when recording is enabled). For more, see RUM Workflow.

API Reference

Functions

  • debug(log)undefined: log a debug message
  • info(log)undefined: informational log
  • warn(log)undefined: warning
  • error(log|Error)undefined: error (string or Error)
  • track(config)undefined: initialise RUM with configuration object
  • setAttributes(config)undefined: update attributes after .track()

Configuration Object

PropertyTypeRequiredDefaultDescription
projectNamestring-Browser application identifier.
serviceNamestringAssociates application instances with traces.
accountKeystringFrom Installation → JavaScript → Create New Application.
targetstring (URL)Ingest endpoint (https://<UID>.middleware.io).
envstring-"prod"Environment tag for filtering.
recordingstring-"1"Session recording mode. "1" enables full session recording (default). "0" collects traces/errors only. "2" disables video if supported by your account.
tracePropagationTargetsArray<RegExp>-Backend hosts to propagate tracing to (omit http(s)://).
tracePropagationFormatstring-"b3"Header format for trace propagation ("b3" or "w3c").
tracerObject-Advanced tracing config and sampling.
defaultAttributesObject<string, string>-Key–value pairs for filtering (e.g., name, email, app.version).
ignoreUrlsArray-URLs to ignore. ignored
ignoreHeadersArray-Headers to avoid capturing/storing.
consoleboolean-trueCapture console logs.
errorsboolean-trueCapture browser errors.

Sampling settings

By default, the browser RUM collects all data. You can pass a custom sampler under tracer:

  • AlwaysSampleSampler (default)
  • AlwaysOffSampler
  • ParentBased
  • SessionBasedSampler (recommended for keeping user journeys intact)

Session-based sampler example (50% of sessions):

1<script>
2  if (window.Middleware) {
3    Middleware.track({
4      serviceName: "service_name",
5      accountKey: "your-account-token",
6      target: "https://<UID>.middleware.io",
7      tracer: {
8        sampler: new Middleware.SessionBasedSampler({ ratio: 0.5 })
9      }
10    });
11  }
12</script>

See the table in Sampling settings for all options.

OptionTypeDefault ValueDescription
rationumber1.0Percentage of sessions reported, ranging from 0.0 to 1.0.
sampledSamplerAlwaysOnSamplerSampler to be used when the session is sampled.
notSampledSamplerAlwaysOffSamplerSampler to be used when the session is not to be sampled.

Troubleshooting

Browser Cookies

The RUM Browser SDK uses first-party cookies to maintain a single user session across pages.

  • _mwRumSessionId_x — stores the current session ID, sampling flag, and expiry. The cookie is extended by 15 minutes on activity (up to 4 hours max).

Script Integration Issues

If you see exceptions during integration, load Middleware scripts earlier in your app lifecycle to avoid collisions. For example:

1setTimeout(() => {
2  if (window.Middleware) {
3    Middleware.track({
4      serviceName: "sample-service",
5      projectName: "sample-project",
6      accountKey: "REDACTED",
7      target: "<target-url>"
8    });
9  }
10}, 10000);

This pattern can help in complex boot orders; prefer initialising as early as possible.

Unable to See Session Recording

  • Confirm the origin URL is correct for the site being recorded.
  • Check the browser’s Network tab for ad-blockers or extensions that may block requests.

Unhandled Promise Rejection: TypeError: Failed to fetch

This can occur if an API call is in flight while the user refreshes. It does not impact the RUM Browser SDK.

Content Security Policy (CSP) & Firewalls

If you use a CSP, allow the Middleware script CDN (from Step 2) and your ingest target in connect-src.

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';
  • Adjust for your policy (nonces/hashes, stricter style-src, etc.).
  • Re-validate CSP if you change SDK/CDN versions later.

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