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.
envandrecordingare 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 seerecording: "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.
Consent (GDPR/CCPA)
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:
tracePropagationTargetsomithttp(s)://and should match the hosts you call from the browser.tracePropagationFormatcontrols 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 messageinfo(log)→undefined: informational logwarn(log)→undefined: warningerror(log|Error)→undefined: error (string orError)track(config)→undefined: initialise RUM with configuration objectsetAttributes(config)→undefined: update attributes after.track()
Configuration Object
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
projectName | string | ✅ | - | Browser application identifier. |
serviceName | string | ✅ | Associates application instances with traces. | |
accountKey | string | ✅ | From Installation → JavaScript → Create New Application. | |
target | string (URL) | ✅ | Ingest endpoint (https://<UID>.middleware.io). | |
env | string | - | "prod" | Environment tag for filtering. |
recording | string | - | "1" | Session recording mode. "1" enables full session recording (default). "0" collects traces/errors only. "2" disables video if supported by your account. |
tracePropagationTargets | Array<RegExp> | - | Backend hosts to propagate tracing to (omit http(s)://). | |
tracePropagationFormat | string | - | "b3" | Header format for trace propagation ("b3" or "w3c"). |
tracer | Object | - | Advanced tracing config and sampling. | |
defaultAttributes | Object<string, string> | - | Key–value pairs for filtering (e.g., name, email, app.version). | |
ignoreUrls | Array | - | URLs to ignore. ignored | |
ignoreHeaders | Array | - | Headers to avoid capturing/storing. | |
console | boolean | - | true | Capture console logs. |
errors | boolean | - | true | Capture browser errors. |
Sampling settings
By default, the browser RUM collects all data. You can pass a custom sampler under tracer:
AlwaysSampleSampler(default)AlwaysOffSamplerParentBasedSessionBasedSampler(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.
| Option | Type | Default Value | Description |
|---|---|---|---|
ratio | number | 1.0 | Percentage of sessions reported, ranging from 0.0 to 1.0. |
sampled | Sampler | AlwaysOnSampler | Sampler to be used when the session is sampled. |
notSampled | Sampler | AlwaysOffSampler | Sampler 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.