Skip to main content
Technology & EngineeringError Tracking Services224 lines

Datadog Rum

Integrating Datadog Real User Monitoring for frontend error tracking, performance monitoring, and session replay within the Datadog observability platform

Quick Summary31 lines
You are an expert in integrating Datadog Real User Monitoring (RUM) for error tracking and frontend observability.

## Key Points

- `mask-user-input`: masks form inputs (default).
- `mask`: masks all text content.
- `allow`: no masking (use only for internal tools).
- RUM error counts by view, version, or browser.
- Core Web Vitals (LCP, FID, CLS) trends.
- Session replay links alongside error details.
- Backend APM metrics on the same dashboard.
- Error rate exceeds threshold per service/version.
- Core Web Vitals degrade beyond acceptable limits.
- Specific error messages appear for the first time.
- Set `sessionReplaySampleRate` to 10-20% in production to balance cost with debugging value; use 100% for staging.
- Always configure `allowedTracingUrls` to connect frontend errors to backend traces for full-stack debugging.

## Quick Example

```bash
npm install @datadog/browser-rum
```

```bash
npx @datadog/datadog-ci sourcemaps upload ./dist \
  --service my-web-app \
  --release-version 1.2.0 \
  --minified-path-prefix https://example.com/
```
skilldb get error-tracking-services-skills/Datadog RumFull skill: 224 lines
Paste into your CLAUDE.md or agent config

Datadog RUM — Error Tracking

You are an expert in integrating Datadog Real User Monitoring (RUM) for error tracking and frontend observability.

Core Philosophy

Overview

Datadog RUM is a real user monitoring solution that is part of the broader Datadog observability platform. It captures frontend errors, performance metrics, user sessions, and connects them to backend traces via distributed tracing. Use Datadog RUM when your team already uses Datadog for infrastructure/APM and you want unified frontend-to-backend observability in a single platform.

Setup & Configuration

JavaScript Browser (CDN)

<script
  src="https://www.datadoghq-browser-agent.com/us1/v5/datadog-rum.js"
  type="text/javascript"
></script>
<script>
  window.DD_RUM &&
    window.DD_RUM.init({
      clientToken: "YOUR_CLIENT_TOKEN",
      applicationId: "YOUR_APPLICATION_ID",
      site: "datadoghq.com",
      service: "my-web-app",
      env: "production",
      version: "1.2.0",
      sessionSampleRate: 100,
      sessionReplaySampleRate: 20,
      trackUserInteractions: true,
      trackResources: true,
      trackLongTasks: true,
      defaultPrivacyLevel: "mask-user-input",
    });
</script>

JavaScript Browser (npm)

npm install @datadog/browser-rum
import { datadogRum } from "@datadog/browser-rum";

datadogRum.init({
  clientToken: "YOUR_CLIENT_TOKEN",
  applicationId: "YOUR_APPLICATION_ID",
  site: "datadoghq.com",
  service: "my-web-app",
  env: "production",
  version: "1.2.0",
  sessionSampleRate: 100,
  sessionReplaySampleRate: 20,
  trackUserInteractions: true,
  trackResources: true,
  trackLongTasks: true,
  defaultPrivacyLevel: "mask-user-input",
});

Connecting to Backend Traces

datadogRum.init({
  // ... other config
  allowedTracingUrls: [
    { match: "https://api.example.com", propagatorTypes: ["tracecontext"] },
  ],
});

React Error Boundary

import { datadogRum } from "@datadog/browser-rum";
import React from "react";

class DatadogErrorBoundary extends React.Component {
  componentDidCatch(error, errorInfo) {
    datadogRum.addError(error, {
      componentStack: errorInfo.componentStack,
    });
  }

  render() {
    return this.props.children;
  }
}

Core Patterns

Error Capturing

// Capture a custom error
try {
  riskyOperation();
} catch (error) {
  datadogRum.addError(error, {
    source: "custom",
    context: { orderId: "abc-123" },
  });
}

// Errors from unhandled exceptions and promise rejections
// are captured automatically

Context and Breadcrumbs

// Set global context
datadogRum.setGlobalContextProperty("team", "checkout");

// Add custom action (serves as breadcrumb)
datadogRum.addAction("checkout_started", {
  cartItems: 3,
  cartTotal: 49.99,
});

User Identification

datadogRum.setUser({
  id: "user-42",
  name: "Jane Doe",
  email: "user@example.com",
  plan: "enterprise",
});

// Clear user on logout
datadogRum.clearUser();

Release Tracking

Set the version parameter in the init() call. Datadog correlates errors with versions automatically. Upload source maps for readable stack traces:

npx @datadog/datadog-ci sourcemaps upload ./dist \
  --service my-web-app \
  --release-version 1.2.0 \
  --minified-path-prefix https://example.com/

Source Maps

npm install --save-dev @datadog/datadog-ci

Add to your CI/CD pipeline after the build step. The --minified-path-prefix must match the URL where assets are served.

Advanced Features

Session Replay

Session replay records DOM snapshots and user interactions. Configure privacy levels:

  • mask-user-input: masks form inputs (default).
  • mask: masks all text content.
  • allow: no masking (use only for internal tools).
// Start recording manually (if not using automatic sampling)
datadogRum.startSessionReplayRecording();

Frontend-to-Backend Correlation

When allowedTracingUrls is configured, Datadog RUM injects trace headers into fetch/XHR requests. This connects browser sessions to backend APM traces, letting you follow a user action from click to database query.

Custom Dashboards

Build dashboards in Datadog combining:

  • RUM error counts by view, version, or browser.
  • Core Web Vitals (LCP, FID, CLS) trends.
  • Session replay links alongside error details.
  • Backend APM metrics on the same dashboard.

Alerting

Create monitors on RUM data:

  • Error rate exceeds threshold per service/version.
  • Core Web Vitals degrade beyond acceptable limits.
  • Specific error messages appear for the first time.

Best Practices

  • Set sessionReplaySampleRate to 10-20% in production to balance cost with debugging value; use 100% for staging.
  • Always configure allowedTracingUrls to connect frontend errors to backend traces for full-stack debugging.
  • Use defaultPrivacyLevel: "mask-user-input" as a baseline and only relax it for internal applications.
  • Set service, env, and version consistently to enable filtering and correlation across Datadog products.
  • Upload source maps in CI/CD with the exact matching version string to get readable stack traces.

Common Pitfalls

  • Mismatching the version string between init() and the source map upload, resulting in unresolved stack traces.
  • Setting sessionSampleRate too low and not having enough data for meaningful performance analysis.
  • Forgetting to configure allowedTracingUrls, losing the frontend-to-backend trace correlation.
  • Not setting defaultPrivacyLevel, potentially capturing sensitive user input in session replays.
  • Using Datadog RUM without the broader Datadog platform, missing the primary value of unified observability.

Anti-Patterns

Over-engineering for hypothetical scale. Building for millions of users when you have hundreds adds complexity without value. Solve today's problems first.

Ignoring the existing ecosystem. Reinventing functionality that mature libraries already provide well wastes time and introduces unnecessary risk.

Premature abstraction. Creating elaborate frameworks and utilities before you have enough concrete cases to know what the abstraction should look like produces the wrong abstraction.

Neglecting error handling at boundaries. Internal code can trust its inputs, but system boundaries (user input, APIs, file I/O) require defensive validation.

Skipping documentation for obvious code. What is obvious to you today will not be obvious to your colleague next month or to you next year.

Install this skill directly: skilldb add error-tracking-services-skills

Get CLI access →