---
title: Advanced Configuration
description: >-
  Configure RUM Browser SDK to modify data collection, override view names,
  manage user sessions, and control sampling for your application's needs.
breadcrumbs: >-
  Docs > RUM & Session Replay > Application Monitoring > RUM Browser Monitoring
  > Advanced Configuration
---

# Advanced Configuration

## Overview{% #overview %}

There are various ways you can modify the [data and context collected](https://docs.datadoghq.com/real_user_monitoring/application_monitoring/browser/data_collected/) by RUM, to support your needs for:

- Protecting sensitive data like personally identifiable information.
- Connecting a user session with your internal identification of that user, to help with support.
- Reducing how much RUM data you're collecting, through sampling the data.
- Providing more context than what the default attributes provide about where the data is coming from.

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 2.17.0" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 2.17.0

## Override default RUM view names{% #override-default-rum-view-names %}

Starting with [version 2.17.0](https://github.com/DataDog/browser-sdk/blob/main/CHANGELOG.md#v2170), you can add view names and assign them to a dedicated service owned by a team by tracking view events manually with the `trackViewsManually` option.

The RUM Browser SDK automatically generates a [view event](https://docs.datadoghq.com/real_user_monitoring/application_monitoring/browser/monitoring_page_performance/) for each new page visited by your users, or when the page URL is changed (for single-page applications). A view name is computed from the current page URL, where variable IDs are removed automatically. A path segment that contains at least one number is considered a variable ID. For example, `/dashboard/1234` and `/dashboard/9a` become `/dashboard/?`.

To override default RUM view names:

1. Set `trackViewsManually` to true when initializing the RUM Browser SDK.

   {% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

   ```
   import { datadogRum } from '@datadog/browser-rum';
   
   datadogRum.init({
         ...,
         trackViewsManually: true,
         ...
   });
   ```
   {% /section %}

   {% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

   ```
   window.DD_RUM.onReady(function() {
         window.DD_RUM.init({
            ...,
            trackViewsManually: true,
            ...
         })
   })
   ```
   {% /section %}

   {% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

   ```
   window.DD_RUM &&
         window.DD_RUM.init({
            ...,
            trackViewsManually: true,
            ...
         });
   ```
   {% /section %}

1. You must start views for each new page or route change (for single-page applications). RUM data is collected when the view starts.
{% /section %}

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 4.13.0" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 4.13.0

### Define service name and version{% #define-service-name-and-version %}

Starting with [version 4.13.0](https://github.com/DataDog/browser-sdk/blob/main/CHANGELOG.md#v4130), you can also optionally define the associated service name and version.

- **View Name**: Defaults to the page URL path.
- **Service**: Defaults to the default service specified when creating your RUM application.
- **Version**: Defaults to the default version specified when creating your RUM application.
{% /section %}

{% section
   displayed-if="The selected value for SDK version is included in the given list: '<2.13.0, >=2.13.0, >=2.17.0'" %}
This section only applies to users who meet the following criteria: The selected value for SDK version is included in the given list: '<2.13.0, >=2.13.0, >=2.17.0'

## Manually track pageviews{% #manually-track-pageviews %}

The following example manually tracks the pageviews on the `checkout` page in a RUM application. No service or version can be specified.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.startView('checkout')
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
        window.DD_RUM.startView('checkout')
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.startView('checkout')
```
{% /section %}
{% /section %}

{% section
   displayed-if="The selected value for SDK version is included in the given list: '>=4.13.0, >=4.49.0, >=5.22.0'" %}
This section only applies to users who meet the following criteria: The selected value for SDK version is included in the given list: '>=4.13.0, >=4.49.0, >=5.22.0'

The following example manually tracks the pageviews on the `checkout` page in a RUM application. It uses `checkout` for the view name and associates the `purchase` service with version `1.2.3`.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.startView({
  name: 'checkout',
  service: 'purchase',
  version: '1.2.3'
})
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
  window.DD_RUM.startView({
    name: 'checkout',
    service: 'purchase',
    version: '1.2.3'
  })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.startView({
  name: 'checkout',
  service: 'purchase',
  version: '1.2.3'
})
```
{% /section %}
{% /section %}

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 5.28.0" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 5.28.0

- **Context**: Starting with [version 5.28.0](https://github.com/DataDog/browser-sdk/blob/main/CHANGELOG.md#v5280), you can add context to views and the child events of views.

The following example manually tracks the pageviews on the `checkout` page in a RUM application. Use `checkout` for the view name and associate the `purchase` service with version `1.2.3`.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.startView({
     name: 'checkout',
     service: 'purchase',
     version: '1.2.3',
     context: {
         payment: 'Done'
     },
})
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
   window.DD_RUM.startView({
         name: 'checkout',
         service: 'purchase',
         version: '1.2.3',
         context: {
             payment: 'Done'
         },
   })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.startView({
     name: 'checkout',
     service: 'purchase',
     version: '1.2.3',
     context: {
         payment: 'Done'
     },
})
```
{% /section %}
{% /section %}

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 2.17.0" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 2.17.0

### React router instrumentation{% #react-router-instrumentation %}

If you are using React, Angular, Vue, or any other frontend framework, Datadog recommends implementing the `startView` logic at the framework router level.

To override default RUM view names so that they are aligned with how you've defined them in your React application, you need to follow the below steps.

**Note**: These instructions are specific to the **React Router v6** library.

1. Set `trackViewsManually` to `true` when initializing the RUM browser SDK as described above.

1. Start views for each route change.

   {% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

   ```
   import { matchRoutes, useLocation } from 'react-router-dom';
   import { routes } from 'path/to/routes';
   import { datadogRum } from "@datadog/browser-rum";
   
   export default function App() {
      // Track every route change with useLocation API
      let location = useLocation();
   
      useEffect(() => {
      const routeMatches = matchRoutes(routes, location.pathname);
      const viewName = routeMatches && computeViewName(routeMatches);
      if (viewName) {
         datadogRum.startView({name: viewName});
      }
      }, [location.pathname]);
   
      ...
   }
   
   // Compute view name out of routeMatches
   function computeViewName(routeMatches) {
      let viewName = "";
      for (let index = 0; index < routeMatches.length; index++) {
      const routeMatch = routeMatches[index];
      const path = routeMatch.route.path;
      // Skip pathless routes
      if (!path) {
         continue;
      }
   
      if (path.startsWith("/")) {
         // Handle absolute child route paths
         viewName = path;
      } else {
         // Handle route paths ending with "/"
         viewName += viewName.endsWith("/") ? path : `/${path}`;
      }
      }
   
      return viewName || '/';
   }
   ```
   {% /section %}

   {% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

   ```
   import { matchRoutes, useLocation } from 'react-router-dom';
   import { routes } from 'path/to/routes';
   
   export default function App() {
      // Track every route change with useLocation API
      let location = useLocation();
   
      useEffect(() => {
      const routeMatches = matchRoutes(routes, location.pathname);
      const viewName = routeMatches && computeViewName(routeMatches);
      if (viewName) {
         DD_RUM.onReady(function() {
            DD_RUM.startView({name: viewName});
         });
      }
      }, [location.pathname]);
   
      ...
   }
   
   // Compute view name out of routeMatches
   function computeViewName(routeMatches) {
      let viewName = "";
      for (let index = 0; index < routeMatches.length; index++) {
      const routeMatch = routeMatches[index];
      const path = routeMatch.route.path;
      // Skip pathless routes
      if (!path) {
         continue;
      }
   
      if (path.startsWith("/")) {
         // Handle absolute child route paths
         viewName = path;
      } else {
         // Handle route paths ending with "/"
         viewName += viewName.endsWith("/") ? path : `/${path}`;
      }
      }
   
      return viewName || '/';
   }
   ```
   {% /section %}

   {% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

   ```
   import { matchRoutes, useLocation } from 'react-router-dom';
   import { routes } from 'path/to/routes';
   
   export default function App() {
      // Track every route change with useLocation API
      let location = useLocation();
   
      useEffect(() => {
      const routeMatches = matchRoutes(routes, location.pathname);
      const viewName = routeMatches && computeViewName(routeMatches);
      if (viewName) {
         window.DD_RUM &&
            window.DD_RUM.startView({name: viewName});
      }
      }, [location.pathname]);
   
      ...
   }
   
   // Compute view name out of routeMatches
   function computeViewName(routeMatches) {
      let viewName = "";
      for (let index = 0; index < routeMatches.length; index++) {
      const routeMatch = routeMatches[index];
      const path = routeMatch.route.path;
      // Skip pathless routes
      if (!path) {
         continue;
      }
   
      if (path.startsWith("/")) {
         // Handle absolute child route paths
         viewName = path;
      } else {
         // Handle route paths ending with "/"
         viewName += viewName.endsWith("/") ? path : `/${path}`;
      }
      }
   
      return viewName || '/';
   }
   ```
   {% /section %}
{% /section %}

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 2.17.0" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 2.17.0

### Set view name{% #set-view-name %}

Use `setViewName(name: string)` to update the name of the current view. This allows you to change the view name during the view without starting a new one.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.setViewName('<VIEW_NAME>');

// Code example
datadogRum.setViewName('Checkout');
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
   window.DD_RUM.setViewName('<VIEW_NAME>');
})

// Code example
window.DD_RUM.onReady(function() {
   window.DD_RUM.setViewName('Checkout');
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.setViewName('<VIEW_NAME>');

// Code example
window.DD_RUM && window.DD_RUM.setViewName('Checkout');
```
{% /section %}

**Note**: Changing the view name affects the view and its child events from the time the method is called.
{% /section %}

For more information, see [Setup Browser Monitoring](https://docs.datadoghq.com/real_user_monitoring/application_monitoring/browser/setup/).

## Enrich and control RUM data{% #enrich-and-control-rum-data %}

The RUM Browser SDK captures RUM events and populates their main attributes. The `beforeSend` callback function gives you access to every event collected by the RUM Browser SDK before it is sent to Datadog.

Intercepting the RUM events allows you to:

- Enrich your RUM events with additional context attributes
- Modify your RUM events to alter their content or redact sensitive sequences (see list of editable properties)
- Discard selected RUM events

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 2.13.0" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 2.13.0

Starting with [version 2.13.0](https://github.com/DataDog/browser-sdk/blob/main/CHANGELOG.md#v2130), `beforeSend` takes two arguments: the `event` generated by the RUM Browser SDK, and the `context` that triggered the creation of the RUM event.

```
function beforeSend(event, context)
```

The potential `context` values are:

| RUM event type   | Context                                                                                                                                                                                                                                                                 |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| View             | [Location](https://developer.mozilla.org/en-US/docs/Web/API/Location)                                                                                                                                                                                                   |
| Action           | [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) and handling stack                                                                                                                                                                                      |
| Resource (XHR)   | [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest), [PerformanceResourceTiming](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming), and handling stack                                                          |
| Resource (Fetch) | [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request), [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response), [PerformanceResourceTiming](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming), and handling stack |
| Resource (Other) | [PerformanceResourceTiming](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming)                                                                                                                                                                 |
| Error            | [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)                                                                                                                                                                         |
| Long Task        | [PerformanceLongTaskTiming](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongTaskTiming)                                                                                                                                                                 |

For more information, see the [Enrich and control RUM data guide](https://docs.datadoghq.com/real_user_monitoring/guide/enrich-and-control-rum-data).
{% /section %}

### Enrich RUM events{% #enrich-rum-events %}

Along with attributes added with the Global Context API or the Feature Flag data collection, you can add additional context attributes to the event. For example, tag your RUM resource events with data extracted from a fetch response object:

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
   ...,
   beforeSend: (event, context) => {
      // collect a RUM resource's response headers
      if (event.type === 'resource' && event.resource.type === 'fetch') {
            event.context.responseHeaders = Object.fromEntries(context.response.headers)
      }
      return true
   },
   ...
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
   window.DD_RUM.init({
      ...,
      beforeSend: (event, context) => {
            // collect a RUM resource's response headers
            if (event.type === 'resource' && event.resource.type === 'fetch') {
               event.context.responseHeaders = Object.fromEntries(context.response.headers)
            }
            return true
      },
      ...
   })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM &&
   window.DD_RUM.init({
      ...,
      beforeSend: (event, context) => {
            // collect a RUM resource's response headers
            if (event.type === 'resource' && event.resource.type === 'fetch') {
               event.context.responseHeaders = Object.fromEntries(context.response.headers)
            }
            return true
      },
      ...
   });
```
{% /section %}

If a user belongs to multiple teams, add additional key-value pairs in your calls to the Global Context API.

The RUM Browser SDK ignores attributes added outside of `event.context`.

### Enrich RUM events with feature flags{% #enrich-rum-events-with-feature-flags %}

You can [enrich your RUM event data with feature flags](https://docs.datadoghq.com/real_user_monitoring/guide/enrich-and-control-rum-data) to get additional context and visibility into performance monitoring. This lets you determine which users are shown a specific user experience and if it is negatively affecting the user's performance.

### Modify the content of a RUM event{% #modify-the-content-of-a-rum-event %}

For example, to redact email addresses from your web application URLs:

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
   ...,
   beforeSend: (event) => {
      // remove email from view url
      event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
   },
   ...
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
   window.DD_RUM.init({
      ...,
      beforeSend: (event) => {
            // remove email from view url
            event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
      },
      ...
   })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM &&
   window.DD_RUM.init({
      ...,
      beforeSend: (event) => {
            // remove email from view url
            event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED")
      },
      ...
   });
```
{% /section %}

You can update the following event properties:

| Attribute                           | Type   | Description                                                                                                                                           |
| ----------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `view.url`                          | String | The URL of the active web page.                                                                                                                       |
| `view.referrer`                     | String | The URL of the previous web page from which a link to the currently requested page was followed.                                                      |
| `view.name`                         | String | The name of the current view.                                                                                                                         |
| `view.performance.lcp.resource_url` | String | The resource URL for the Largest Contentful Paint.                                                                                                    |
| `service`                           | String | The service name for your application.                                                                                                                |
| `version`                           | String | The application's version. For example: 1.2.3, 6c44da20, or 2020.02.13.                                                                               |
| `action.target.name`                | String | The element that the user interacted with. Only for automatically collected actions.                                                                  |
| `error.message`                     | String | A concise, human-readable, one-line message explaining the error.                                                                                     |
| `error.stack`                       | String | The stack trace or complementary information about the error.                                                                                         |
| `error.resource.url`                | String | The resource URL that triggered the error.                                                                                                            |
| `resource.url`                      | String | The resource URL.                                                                                                                                     |
| `long_task.scripts.source_url`      | String | The script resource url                                                                                                                               |
| `long_task.scripts.invoker`         | String | A meaningful name indicating how the script was called                                                                                                |
| `context`                           | Object | Attributes added with the Global Context API, the View Context API, or when generating events manually (for example, `addError` and **`addAction`**). |

The RUM Browser SDK ignores modifications made to event properties not listed above. For more information about event properties, see the [RUM Browser SDK GitHub repository](https://github.com/DataDog/browser-sdk/blob/main/packages/rum-core/src/rumEvent.types.ts).

**Note**: Unlike other events, view events are sent multiple times to Datadog to reflect the updates occurring during their lifecycle. An update on a previous view event can still be sent while a new view is active. Datadog recommends being mindful of this behavior when modifying the content of a view event.

```
beforeSend: (event) => {
    // discouraged, as the current view name could be applied to both the active view and the previous views
    event.view.name = getCurrentViewName()

    // recommended
    event.view.name = getViewNameForUrl(event.view.url)
}
```

### Discard a RUM event{% #discard-a-rum-event %}

With the `beforeSend` API, discard a RUM event by returning `false`:

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
   ...,
   beforeSend: (event) => {
      if (shouldDiscard(event)) {
         return false
      }
      ...
   },
   ...
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.init({
        ...,
        beforeSend: (event) => {
            if (shouldDiscard(event)) {
                return false
            },
            ...
        },
        ...
    })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM &&
    window.DD_RUM.init({
        ...,
        beforeSend: (event) => {
            if (shouldDiscard(event)) {
                return false
            }
            ...
        },
        ...
    });
```
{% /section %}

**Note**: View events cannot be discarded.

## User session{% #user-session %}

Adding user information to your RUM sessions helps you:

- Follow the journey of a given user
- Know which users are the most impacted by errors
- Monitor performance for your most important users

{% image
   source="https://datadog-docs.imgix.net/images/real_user_monitoring/browser/advanced_configuration/user-api.73b0cac9af174bfd4322133367d6e968.png?auto=format"
   alt="User API in RUM UI" /%}

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 6.4.0" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 6.4.0

In versions 6.4.0 and above, the following attributes are available:

| Attribute   | Type   | Required | Description                                                                                              |
| ----------- | ------ | -------- | -------------------------------------------------------------------------------------------------------- |
| `usr.id`    | String | Yes      | Unique user identifier.                                                                                  |
| `usr.name`  | String | No       | User friendly name, displayed by default in the RUM UI.                                                  |
| `usr.email` | String | No       | User email, displayed in the RUM UI if the user name is not present. It is also used to fetch Gravatars. |
{% /section %}

{% section
   displayed-if="not The selected version for rum_browser_sdk_version is at least 6.4.0" %}
This section only applies to users who meet the following criteria: not The selected version for rum_browser_sdk_version is at least 6.4.0

The below attributes are optional in versions before 6.4.0, but Datadog strongly recommends providing at least one of them. For example, you should set the user ID on your sessions to see relevant data on some default RUM dashboards, which rely on `usr.id` as part of the query.

| Attribute   | Type   | Description                                                                                              |
| ----------- | ------ | -------------------------------------------------------------------------------------------------------- |
| `usr.id`    | String | Unique user identifier.                                                                                  |
| `usr.name`  | String | User friendly name, displayed by default in the RUM UI.                                                  |
| `usr.email` | String | User email, displayed in the RUM UI if the user name is not present. It is also used to fetch Gravatars. |

**Note**: 'Public User' is displayed in the RUM UI when `usr.name` is not set, even if `usr.email` and `usr.id` are defined.

Increase your filtering capabilities by adding extra attributes on top of the recommended ones. For instance, add information about the user plan, or which user group they belong to.

When making changes to the user session object, all RUM events collected after the change contain the updated information.

**Note**: Deleting the user session information, as in a logout, retains the user information on the last view before the logout, but not on later views or the session level as the session data uses the last view's values.
{% /section %}

### Identify user session{% #identify-user-session %}

`datadogRum.setUser(<USER_CONFIG_OBJECT>)`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.setUser({
    id: '1234',
    name: 'John Doe',
    email: 'john@doe.com',
    plan: 'premium',
    ...
})
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.setUser({
        id: '1234',
        name: 'John Doe',
        email: 'john@doe.com',
        plan: 'premium',
        ...
    })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.setUser({
    id: '1234',
    name: 'John Doe',
    email: 'john@doe.com',
    plan: 'premium',
    ...
})
```
{% /section %}

### Access user session{% #access-user-session %}

`datadogRum.getUser()`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.getUser()
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.getUser()
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.getUser()
```
{% /section %}

### Add/Override user session property{% #add-override-user-session-property %}

`datadogRum.setUserProperty('<USER_KEY>', <USER_VALUE>)`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.setUserProperty('name', 'John Doe')
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.setUserProperty('name', 'John Doe')
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.setUserProperty('name', 'John Doe')
```
{% /section %}

### Remove user session property{% #remove-user-session-property %}

`datadogRum.removeUserProperty('<USER_KEY>')`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.removeUserProperty('name')
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.removeUserProperty('name')
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.removeUserProperty('name')
```
{% /section %}

### Clear user session property{% #clear-user-session-property %}

`datadogRum.clearUser()`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.clearUser()
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.clearUser()
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.clearUser()
```
{% /section %}

## Account{% #account %}

To group users into different set, use the account concept.

The following attributes are available:

| Attribute      | Type   | Required | Description                                                |
| -------------- | ------ | -------- | ---------------------------------------------------------- |
| `account.id`   | String | Yes      | Unique account identifier.                                 |
| `account.name` | String | No       | Account friendly name, displayed by default in the RUM UI. |

### Identify account{% #identify-account %}

`datadogRum.setAccount(<ACCOUNT_CONFIG_OBJECT>)`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.setAccount({
    id: '1234',
    name: 'My Company Name',
    ...
})
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.setAccount({
        id: '1234',
        name: 'My Company Name',
        ...
    })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.setAccount({
    id: '1234',
    name: 'My Company Name',
    ...
})
```
{% /section %}

### Access account{% #access-account %}

`datadogRum.getAccount()`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.getAccount()
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.getAccount()
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.getAccount()
```
{% /section %}

### Add/Override account property{% #add-override-account-property %}

`datadogRum.setAccountProperty('<ACCOUNT_KEY>', <ACCOUNT_VALUE>)`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.setAccountProperty('name', 'My Company Name')
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.setAccountProperty('name', 'My Company Name')
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.setAccountProperty('name', 'My Company Name')
```
{% /section %}

### Remove account property{% #remove-account-property %}

`datadogRum.removeAccountProperty('<ACCOUNT_KEY>')`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.removeAccountProperty('name')
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.removeAccountProperty('name')
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.removeAccountProperty('name')
```
{% /section %}

### Clear account properties{% #clear-account-properties %}

`datadogRum.clearAccount()`

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
datadogRum.clearAccount()
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.clearAccount()
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.clearAccount()
```
{% /section %}

## Sampling{% #sampling %}

By default, no sampling is applied on the number of collected sessions. To apply a relative sampling (in percent) to the number of sessions collected, use the `sessionSampleRate` parameter when initializing RUM.

The following example collects only 90% of all sessions on a given RUM application:

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
    applicationId: '<DATADOG_APPLICATION_ID>',
    clientToken: '<DATADOG_CLIENT_TOKEN>',
    site: '<DATADOG_SITE>',
    sessionSampleRate: 90,
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.init({
        clientToken: '<CLIENT_TOKEN>',
        applicationId: '<APPLICATION_ID>',
        site: '<DATADOG_SITE>',
        sessionSampleRate: 90,
    })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM &&
    window.DD_RUM.init({
        clientToken: '<CLIENT_TOKEN>',
        applicationId: '<APPLICATION_ID>',
        site: '<DATADOG_SITE>',
        sessionSampleRate: 90,
    });
```
{% /section %}

For a sampled out session, all pageviews and associated telemetry for that session are not collected.

## User tracking consent{% #user-tracking-consent %}

To be compliant with GDPR, CCPA, and similar regulations, the RUM Browser SDK lets you provide the tracking consent value at initialization. For more information on tracking consent, see [Data Security](https://docs.datadoghq.com/data_security/real_user_monitoring/#browser-rum-use-of-cookies).

The `trackingConsent` initialization parameter can be one of the following values:

1. `"granted"` (default): The RUM Browser SDK starts collecting data and sends it to Datadog.
1. `"not-granted"`: The RUM Browser SDK does not collect any data.

To change the tracking consent value after the RUM Browser SDK is initialized, use the `setTrackingConsent()` API call. The RUM Browser SDK changes its behavior according to the new value:

- when changed from `"granted"` to `"not-granted"`, the RUM session is stopped, data is no longer sent to Datadog.
- when changed from `"not-granted"` to `"granted"`, a new RUM session is created if no previous session is active, and data collection resumes.

This state is not synchronized between tabs nor persisted between navigation. It is your responsibility to provide the user decision during RUM Browser SDK initialization or by using `setTrackingConsent()`.

When `setTrackingConsent()` is used before `init()`, the provided value takes precedence over the initialization parameter.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.init({
    ...,
    trackingConsent: 'not-granted'
});

acceptCookieBannerButton.addEventListener('click', function() {
    datadogRum.setTrackingConsent('granted');
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.init({
        ...,
        trackingConsent: 'not-granted'
    });
});

acceptCookieBannerButton.addEventListener('click', () => {
    window.DD_RUM.onReady(function() {
        window.DD_RUM.setTrackingConsent('granted');
    });
});
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.init({
  ...,
  trackingConsent: 'not-granted'
});

acceptCookieBannerButton.addEventListener('click', () => {
    window.DD_RUM && window.DD_RUM.setTrackingConsent('granted');
});
```
{% /section %}

## View context{% #view-context %}

Starting with [version 5.28.0](https://docs.datadoghq.com/real_user_monitoring/application_monitoring/browser/advanced_configuration#override-default-rum-view-names), the context of view events is modifiable. Context can be added to the current view only, and populates its child events (such as `action`, `error`, and `timing`) with `startView`, `setViewContext`, and `setViewContextProperty` functions.

### Start view with context{% #start-view-with-context %}

Optionally define the context while starting a view with `startView` options.

### Add view context{% #add-view-context %}

Enrich or modify the context of RUM view events and corresponding child events with the `setViewContextProperty(key: string, value: any)` API.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.setViewContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');

// Code example
datadogRum.setViewContextProperty('activity', {
    hasPaid: true,
    amount: 23.42
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.setViewContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.setViewContextProperty('activity', {
        hasPaid: true,
        amount: 23.42
    });
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.setViewContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');

// Code example
window.DD_RUM && window.DD_RUM.setViewContextProperty('activity', {
    hasPaid: true,
    amount: 23.42
});
```
{% /section %}

### Replace view context{% #replace-view-context %}

Replace the context of your RUM view events and corresponding child events with `setViewContext(context: Context)` API.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';
datadogRum.setViewContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });

// Code example
datadogRum.setViewContext({
    originalUrl: 'shopist.io/department/chairs',
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.setViewContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.setViewContext({
      originalUrl: 'shopist.io/department/chairs',
    })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM &&
    window.DD_RUM.setViewContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });

// Code example
window.DD_RUM &&
    window.DD_RUM.setViewContext({
        originalUrl: 'shopist.io/department/chairs',
    });
```
{% /section %}

## Error context{% #error-context %}

### Attaching local error context with dd_context{% #attaching-local-error-context-with-dd-context %}

When capturing errors, additional context may be provided at the time an error is generated. Instead of passing extra information through the `addError()` API, you can attach a `dd_context` property directly to the error instance. The RUM Browser SDK automatically detects this property and merges it into the final error event context.

```
const error = new Error('Something went wrong')
error.dd_context = { component: 'Menu', param: 123, }
throw error
```

## Global context{% #global-context %}

### Add global context property{% #add-global-context-property %}

After RUM is initialized, add extra context to all RUM events collected from your application with the `setGlobalContextProperty(key: string, value: any)` API:

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.setGlobalContextProperty('<CONTEXT_KEY>', <CONTEXT_VALUE>);

// Code example
datadogRum.setGlobalContextProperty('activity', {
    hasPaid: true,
    amount: 23.42
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.setGlobalContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.setGlobalContextProperty('activity', {
        hasPaid: true,
        amount: 23.42
    });
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.setGlobalContextProperty('<CONTEXT_KEY>', '<CONTEXT_VALUE>');

// Code example
window.DD_RUM && window.DD_RUM.setGlobalContextProperty('activity', {
    hasPaid: true,
    amount: 23.42
});
```
{% /section %}

### Remove global context property{% #remove-global-context-property %}

You can remove a previously defined global context property.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';
datadogRum.removeGlobalContextProperty('<CONTEXT_KEY>');

// Code example
datadogRum.removeGlobalContextProperty('codeVersion');
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.removeGlobalContextProperty('<CONTEXT_KEY>');
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.removeGlobalContextProperty('codeVersion');
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM &&
    window.DD_RUM.removeGlobalContextProperty('<CONTEXT_KEY>');

// Code example
window.DD_RUM &&
    window.DD_RUM.removeGlobalContextProperty('codeVersion');
```
{% /section %}

### Replace global context{% #replace-global-context %}

Replace the default context for all your RUM events with the `setGlobalContext(context: Context)` API.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';
datadogRum.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });

// Code example
datadogRum.setGlobalContext({
    codeVersion: 34,
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
    window.DD_RUM.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });
})

// Code example
window.DD_RUM.onReady(function() {
    window.DD_RUM.setGlobalContext({
        codeVersion: 34,
    })
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM &&
    window.DD_RUM.setGlobalContext({ '<CONTEXT_KEY>': '<CONTEXT_VALUE>' });

// Code example
window.DD_RUM &&
    window.DD_RUM.setGlobalContext({
        codeVersion: 34,
    });
```
{% /section %}

### Clear global context{% #clear-global-context %}

You can clear the global context by using `clearGlobalContext`.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

datadogRum.clearGlobalContext();
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
  window.DD_RUM.clearGlobalContext();
});
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.clearGlobalContext();
```
{% /section %}

### Read global context{% #read-global-context %}

Once RUM is initialized, read the global context with the `getGlobalContext()` API.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

const context = datadogRum.getGlobalContext();
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function() {
  const context = window.DD_RUM.getGlobalContext();
});
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
const context = window.DD_RUM && window.DD_RUM.getGlobalContext();
```
{% /section %}

## Contexts life cycle{% #contexts-life-cycle %}

By default, global context and user context are stored in the current page memory, which means they are not:

- kept after a full reload of the page
- shared across different tabs or windows of the same session

To add them to all events of the session, they must be attached to every page.

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 4.49.0" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 4.49.0

With the introduction of the `storeContextsAcrossPages` configuration option in version 4.49.0, those contexts can be stored in [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), allowing the following behaviors:

- Contexts are preserved after a full reload
- Contexts are synchronized between tabs opened on the same origin

However, this feature comes with some **limitations**:

- Setting Personable Identifiable Information (PII) in those contexts is not recommended, as data stored in `localStorage` outlives the user session
- The feature is incompatible with the `trackSessionAcrossSubdomains` options because `localStorage` data is only shared among the same origin (login.site.com ≠ app.site.com)
- `localStorage` is limited to 5 MiB by origin, so the application-specific data, Datadog contexts, and other third-party data stored in local storage must be within this limit to avoid any issues
{% /section %}

## Internal context{% #internal-context %}

After the Datadog browser RUM SDK is initialized, you can access the internal context of the SDK. This provides core identifiers and metadata that the SDK uses internally, such as session IDs and application details.

You can explore the following attributes:

| Attribute      | Description                                                       |
| -------------- | ----------------------------------------------------------------- |
| application_id | ID of the application.                                            |
| session_id     | ID of the session.                                                |
| user_action    | Object containing action ID (or undefined if no action is found). |
| view           | Object containing details about the current view event.           |

For more information, see [RUM Browser Data Collected](https://docs.datadoghq.com/real_user_monitoring/application_monitoring/browser/monitoring_page_performance/).

### Example{% #example %}

```
{
  application_id : "xxx",
  session_id : "xxx",
  user_action: { id: "xxx" },
  view : {
    id : "xxx",
    referrer : "",
    url: "http://localhost:8080/",
    name: "homepage"
  }
}
```

You can optionally use `startTime` parameter to get the context of a specific time. If the parameter is omitted, the current context is returned.

```
getInternalContext (startTime?: 'number' | undefined)
```

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum'

datadogRum.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
window.DD_RUM.onReady(function () {
  window.DD_RUM.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }
})
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
window.DD_RUM && window.DD_RUM.getInternalContext() // { session_id: "xxxx", application_id: "xxxx" ... }
```
{% /section %}

## Micro frontend{% #micro-frontend %}

The RUM Browser SDK supports micro frontend architectures by attributing events to specific micro frontends using `service` and `version` attributes. A single RUM SDK instance runs at the shell level. Events are segmented by `service` and `version` so teams can filter dashboards, set alerts, and track performance per micro frontend.

Datadog provides two approaches for attributing RUM events to micro frontends:

1. **Automatic attribution**: Uses a build plugin that injects source code context, eliminating manual stack trace parsing
1. **Manual attribution**: Uses the `beforeSend` callback to parse stack traces and extract service information

### Automatic service and version attribution{% #automatic-service-and-version-attribution %}

This approach uses a build plugin to inject source code context into your bundles, which the RUM SDK automatically reads to enrich events with the correct `service` and `version`.

#### Prerequisites and supported setups{% #prerequisites-and-supported-setups %}

- **Separated bundles**: Each micro frontend has its own bundle with distinct file paths, for example, using [module federation](https://module-federation.io/).
- **Supported bundler**: Use a bundler [supported by the Datadog build plugins](https://github.com/DataDog/build-plugins?tab=readme-ov-file#usage).
- **Browser SDK**: Browser SDK version v6.30.1 or higher.

#### Setup guide{% #setup-guide %}

**Step 1 - Configure the [build plugin](https://github.com/DataDog/build-plugins) for each micro frontend**

In each micro frontend's build configuration, enable source code context injection:

{% tab title="Webpack" %}

```
const { datadogWebpackPlugin } = require('@datadog/webpack-plugin');

module.exports = {
    plugins: [
        new datadogWebpackPlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
};
```

{% /tab %}

{% tab title="Vite" %}

```
import { datadogVitePlugin } from '@datadog/vite-plugin';

export default {
    plugins: [
        datadogVitePlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
};
```

{% /tab %}

{% tab title="esbuild" %}

```
const { datadogEsbuildPlugin } = require('@datadog/esbuild-plugin');

require('esbuild').build({
    plugins: [
        datadogEsbuildPlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
});
```

{% /tab %}

{% tab title="Rollup" %}

```
import { datadogRollupPlugin } from '@datadog/rollup-plugin';

export default {
    plugins: [
        datadogRollupPlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
};
```

{% /tab %}

{% tab title="Rspack" %}

```
const { datadogRspackPlugin } = require('@datadog/rspack-plugin');

module.exports = {
    plugins: [
        new datadogRspackPlugin({
            rum: {
                enable: true,
                sourceCodeContext: {
                    service: 'foo-microfrontend',
                    version: process.env.APP_VERSION || '1.0.0'
                }
            }
        })
    ]
};
```

{% /tab %}

**Step 2 - Set up the Browser SDK at the shell level**

[Set up Browser Monitoring](https://docs.datadoghq.com/real_user_monitoring/application_monitoring/browser/setup/) in your shell application (main entry point). The Browser SDK automatically enriches RUM events (errors, custom actions, XHR/Fetch resources, long tasks, vitals) with `service` and `version` from the context map.

{% alert level="warning" %}
Events that don't match any micro frontend fall back to the shell-level service and version.
{% /alert %}

**Step 3 - Explore micro frontend data in Datadog**

{% section
   displayed-if="The selected version for rum_browser_sdk_version is at least 5.22" %}
This section only applies to users who meet the following criteria: The selected version for rum_browser_sdk_version is at least 5.22

### Manual service and version attribution{% #manual-service-and-version-attribution %}

In the `beforeSend` property, you can override the service and version properties. To help you identify where the event originated, use the `context.handlingStack` property.

{% section displayed-if="Source is NPM" %}
This section only applies to users who meet the following criteria: Source is NPM

```
import { datadogRum } from '@datadog/browser-rum';

const SERVICE_REGEX = /some-pathname\/(?<service>\w+)\/(?<version>\w+)\//;

datadogRum.init({
    ...,
    beforeSend: (event, context) => {
        const stack = context?.handlingStack || event?.error?.stack;
        const { service, version } = stack?.match(SERVICE_REGEX)?.groups;

        if (service && version) {
          event.service = service;
          event.version = version;
        }

        return true;
    },
});
```
{% /section %}

{% section displayed-if="Source is CDN async" %}
This section only applies to users who meet the following criteria: Source is CDN async

```
const SERVICE_REGEX = /some-pathname\/(?<service>\w+)\/(?<version>\w+)\//;

window.DD_RUM.onReady(function() {
    window.DD_RUM.init({
        ...,
        beforeSend: (event, context) => {
            const stack = context?.handlingStack || event?.error?.stack;
            const { service, version } = stack?.match(SERVICE_REGEX)?.groups;

            if (service && version) {
                event.service = service;
                event.version = version;
            }

            return true;
        },
    });
});
```
{% /section %}

{% section displayed-if="Source is CDN sync" %}
This section only applies to users who meet the following criteria: Source is CDN sync

```
const SERVICE_REGEX = /some-pathname\/(?<service>\w+)\/(?<version>\w+)\//;

window.DD_RUM && window.DD_RUM.init({
    ...,
    beforeSend: (event, context) => {
        const stack = context?.handlingStack || event?.error?.stack;
        const { service, version } = stack?.match(SERVICE_REGEX)?.groups;

        if (service && version) {
          event.service = service;
          event.version = version;
        }

        return true;
    },
});
```
{% /section %}

The regular expression must match your application's file path structure. Adjust the pattern to extract service and version from your bundle URLs. Any query in the RUM Explorer can use the service attribute to filter events.
{% /section %}

### Limitations{% #limitations %}

Some events cannot be attributed to an origin because they do not have an associated handling stack:

- Action events collected automatically
- Resource events other than XHR and Fetch
- View events collected automatically
- CORS and CSP violations

### Explore micro frontend data in Datadog{% #explore-micro-frontend-data-in-datadog %}

After setup, the `service` and `version` on RUM events identify which micro frontend generated each event. Use these attributes in several places in Datadog:

- **Side panels**: The `service` and `version` attributes appear in the session, view, error, resource, action, and long task side panels in the RUM Explorer.
- **RUM Summary dashboard**: Use the `service` and `version` to filter in the RUM Summary dashboard to scope performance metrics to a specific micro frontend.
- **Custom dashboards**: Create dashboards using the `service` and `version` to monitor each micro frontend independently.

## Further reading{% #further-reading %}

- [Tracking User Actions](https://docs.datadoghq.com/real_user_monitoring/application_monitoring/browser/tracking_user_actions)
- [Real User Monitoring](https://www.datadoghq.com/blog/real-user-monitoring-with-datadog/)
- [RUM browser data collected](https://docs.datadoghq.com/real_user_monitoring/application_monitoring/browser/data_collected/)
- [Explore your views within Datadog](https://docs.datadoghq.com/real_user_monitoring/explorer/)
- [Apply visualizations on your events](https://docs.datadoghq.com/real_user_monitoring/explorer/visualize/)
- [Datadog standard attributes](https://docs.datadoghq.com/logs/log_configuration/attributes_naming_convention)

{% image
   source="https://datadog-docs.imgix.net/images/real_user_monitoring/browser/advanced_configuration/user-api.73b0cac9af174bfd4322133367d6e968.png?auto=format"
   alt="" /%}
