Skip to content

Frontend Framework Plugin Integration

Starting from RUM SDK 3.3.6, framework plugins can be used to collect framework router Views and framework errors.
Framework plugins are independent of the main RUM package. An application only needs to install the plugins it actually uses.

Supported Ranges

Framework Supported Versions Router Capability Error Capability
React React 18, 19; React Router 6, 7, 8; TanStack Router 1.x Names Views using route templates, ignore only query or hash changes ErrorBoundary, addReactError()
Vue Vue 2.7 + Vue Router 3; Vue 3 + Vue Router 4 Names Views using matched route templates, ignore only query changes Vue global error handler, addVueError()
Angular Angular 15 to 22; RxJS 7 and above Starts View after NavigationEnd, ignores canceled, failed, or only query or hash changes Angular ErrorHandler, addAngularError()
Next.js Next.js 13 and above, React 18 and above Supports App Router and Pages Router See SSR framework access
Nuxt Nuxt 3, 4; Vue 3; Vue Router 4 Supports Nuxt file-based routing and client-side navigation See SSR framework access
Version Requirements

The main RUM package version must not be lower than the framework plugin version. An application can only initialize either the full RUM package or the slim RUM package, not both at the same time.

The full RUM package supports Session Replay and compressed reporting; the slim RUM package does not include these two capabilities.
Both RUM packages can use framework plugins to collect Views and Errors.

When using the slim RUM package, only replace the RUM import, the framework plugin configuration remains unchanged:

import { datafluxRum } from "@cloudcare/browser-rum-slim"

The following examples use the public OpenWay's site and clientToken. When connecting directly via DataKit, replace these two parameters with datakitOrigin. Do not configure both reporting addresses simultaneously.

React

Installation

npm install @cloudcare/browser-rum @cloudcare/browser-rum-react

React Router

To enable Router integration, you need to:

  1. Set router: true in reactPlugin();
  2. Import the Router creation API, Routes, or useRoutes from the plugin subpath matching the React Router major version.

The following example uses React Router 6:

import { RouterProvider } from "react-router-dom"
import { datafluxRum } from "@cloudcare/browser-rum"
import { reactPlugin } from "@cloudcare/browser-rum-react"
import {
  createBrowserRouter,
} from "@cloudcare/browser-rum-react/react-router-v6"

const router = createBrowserRouter([
  { path: "/", element: <Home /> },
  { path: "/users/:id", element: <UserDetail /> },
])

datafluxRum.init({
  applicationId: "<APPLICATION_ID>",
  site: "<PUBLIC_OPENWAY_URL>",
  clientToken: "<CLIENT_TOKEN>",
  service: "web-react",
  env: "production",
  version: "1.0.0",
  sessionSampleRate: 100,
  plugins: [reactPlugin({ router: true })],
})

root.render(<RouterProvider router={router} />)

Select the entry based on the Router version:

Router Plugin Entry APIs exported from the plugin entry
React Router 6 @cloudcare/browser-rum-react/react-router-v6 createBrowserRouter, createHashRouter, createMemoryRouter, Routes, useRoutes
React Router 7 @cloudcare/browser-rum-react/react-router-v7 Same as above
React Router 8 @cloudcare/browser-rum-react/react-router-v8 Same as above
TanStack Router 1.x @cloudcare/browser-rum-react/tanstack-router createRouter

Other Router APIs are still imported from the Router package installed in the application. Do not import Router wrappers from the framework plugin's main entry, otherwise the plugin cannot distinguish the Router major version.

React Errors

Use ErrorBoundary at the application root node or around critical business areas:

import { ErrorBoundary } from "@cloudcare/browser-rum-react"

root.render(
  <ErrorBoundary
    fallback={({ resetError }) => (
      <button type="button" onClick={resetError}>Retry</button>
    )}
    context={{ module: "checkout" }}
  >
    <App />
  </ErrorBoundary>
)

If you already have an ErrorBoundary, React 19 root error callback, or manually caught errors, call addReactError(error, errorInfo, context). React Error events will include context.framework = react, and if a component stack exists, context.component_stack will also be included.

Vue

Installation

npm install @cloudcare/browser-rum @cloudcare/browser-rum-vue

Vue 3 and Vue Router 4

import { createApp } from "vue"
import { createWebHistory } from "vue-router"
import { datafluxRum } from "@cloudcare/browser-rum"
import { vuePlugin } from "@cloudcare/browser-rum-vue"
import {
  createRouter,
} from "@cloudcare/browser-rum-vue/vue-router-v4"

const app = createApp(App)
const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: "/", component: Home },
    { path: "/users/:id", component: UserDetail },
  ],
})

datafluxRum.init({
  applicationId: "<APPLICATION_ID>",
  site: "<PUBLIC_OPENWAY_URL>",
  clientToken: "<CLIENT_TOKEN>",
  service: "web-vue",
  env: "production",
  version: "1.0.0",
  sessionSampleRate: 100,
  plugins: [vuePlugin({ app, router: true })],
})

app.use(router)
app.mount("#app")

After passing in app, the plugin will install the Vue global error handler, while preserving any existing app.config.errorHandler in the application.

Vue 2.7 and Vue Router 3

import Vue from "vue"
import { datafluxRum } from "@cloudcare/browser-rum"
import { vuePlugin } from "@cloudcare/browser-rum-vue"
import VueRouter from "@cloudcare/browser-rum-vue/vue-router-v3"

Vue.use(VueRouter)
const router = new VueRouter({ routes })

datafluxRum.init({
  applicationId: "<APPLICATION_ID>",
  site: "<PUBLIC_OPENWAY_URL>",
  clientToken: "<CLIENT_TOKEN>",
  plugins: [vuePlugin({ app: Vue, router: true })],
})

new Vue({ router, render: (h) => h(App) }).$mount("#app")

If you already have a custom error handler, you can also call addVueError(error, componentInstance, info, context). Vue Error events will include context.framework = vue, and will record the component name and component path if possible.

Angular

Installation

npm install @cloudcare/browser-rum @cloudcare/browser-rum-angular

Standalone Application

import { bootstrapApplication } from "@angular/platform-browser"
import { provideRouter } from "@angular/router"
import { datafluxRum } from "@cloudcare/browser-rum"
import { angularPlugin } from "@cloudcare/browser-rum-angular"
import {
  provideRumErrorHandler,
  provideRumRouter,
} from "@cloudcare/browser-rum-angular/providers"

datafluxRum.init({
  applicationId: "<APPLICATION_ID>",
  site: "<PUBLIC_OPENWAY_URL>",
  clientToken: "<CLIENT_TOKEN>",
  service: "web-angular",
  env: "production",
  version: "1.0.0",
  sessionSampleRate: 100,
  plugins: [angularPlugin({ router: true })],
})

bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(routes),
    provideRumRouter(),
    provideRumErrorHandler(),
  ],
})

provideRumRouter() only starts a View after the Angular Router successfully triggers NavigationEnd. Canceled or failed navigations do not generate Views. provideRumErrorHandler() reports Errors while preserving Angular's default console error handling behavior.

If you already have a custom ErrorHandler, you can call addAngularError(error, context); if you already have a custom Router integration, you can call trackAngularRouter(router).

View Naming and Lifecycle

After enabling the framework Router integration, the plugin will take over manual Views:

Scenario Collection Behavior
First entry into a route Creates an initial View
Pathname change with successful navigation Creates a new View
Only query change Does not create a new View
Only hash change React, Angular do not create a new View; Nuxt can track hash routes
Dynamic routes Uses template names like /users/:id, /users/[id], etc.
Navigation canceled, failed, or new page not committed Does not create a View

Do not use both the Router plugin and datafluxRum.startView() in business code to track the same route, otherwise duplicate Views may be generated.

The React, Vue, and Angular plugins all support the getViewName callback. Returning a custom string can override the default route template; returning undefined will skip creating a View for the current route.

Verifying Integration

  1. Open the browser developer tools, filter by /v1/write/rum in the Network tab.
  2. Navigate to a dynamic route, for example, from /users/1 to /users/2.
  3. Confirm that the View name remains as the route template, not the specific user ID.
  4. Modify only the query parameters, confirm that no duplicate Views are created.
  5. Trigger a framework rendering error, confirm that an event with type=error appears, along with the corresponding context.framework.

Frequently Asked Questions

No View after enabling router: true

Ensure that the Router creation API, Routes, or useRoutes are imported from the plugin subpath matching the current Router major version. If you only register the plugin but continue using the original Router creation API, the plugin cannot obtain the full route state.

Multiple Views generated for a single route navigation

Ensure that the Router plugin is not registered multiple times, and that no extra call to datafluxRum.startView() is made for the same route change.

Dynamic routes generate a large number of View names

Prefer using Router template paths. If a stable name cannot be automatically obtained from the route configuration, use getViewName to map entity IDs to fixed business names.

Feedback

Is this page helpful? ×