프론트엔드 프레임워크 플러그인 연동¶
RUM SDK 3.3.6부터 독립형 프레임워크 플러그인을 통해 프레임워크 라우팅 View와 프레임워크 오류를 수집할 수 있습니다. 프레임워크 플러그인은 RUM 메인 패키지와 독립적으로 유지되며, 애플리케이션은 실제로 사용하는 플러그인만 설치하면 됩니다.
지원 범위¶
| 프레임워크 | 지원 버전 | 라우팅 기능 | 오류 기능 |
|---|---|---|---|
| React | React 18, 19; React Router 6, 7, 8; TanStack Router 1.x | 라우팅 템플릿을 사용하여 View 이름 지정, query 또는 hash 변경만 있는 경우 무시 | ErrorBoundary, addReactError() |
| Vue | Vue 2.7 + Vue Router 3; Vue 3 + Vue Router 4 | 일치하는 라우팅 템플릿을 사용하여 View 이름 지정, query 변경만 있는 경우 무시 | Vue 전역 오류 핸들러, addVueError() |
| Angular | Angular 15 ~ 22; RxJS 7 이상 | NavigationEnd 이후 View 시작, 취소, 실패 및 query 또는 hash 변경만 있는 경우 무시 |
Angular ErrorHandler, addAngularError() |
| Next.js | Next.js 13 이상, React 18 이상 | App Router 및 Pages Router 지원 | SSR 프레임워크 연동 참조 |
| Nuxt | Nuxt 3, 4; Vue 3; Vue Router 4 | Nuxt 파일 라우팅 및 클라이언트 사이드 네비게이션 지원 | SSR 프레임워크 연동 참조 |
버전 요구사항
RUM 메인 패키지 버전은 프레임워크 플러그인 버전보다 낮으면 안 됩니다. 하나의 애플리케이션은 전체 RUM 패키지 또는 간소화된 RUM 패키지 중 하나만 초기화할 수 있으며, 두 RUM 인스턴스를 동시에 초기화하지 마십시오.
전체 RUM 패키지는 Session Replay 및 압축 업로드를 지원합니다. 간소화된 RUM 패키지에는 이 두 가지 기능이 포함되어 있지 않습니다. 두 RUM 패키지 모두 프레임워크 플러그인을 사용하여 View와 Error를 수집할 수 있습니다.
간소화된 RUM 패키지를 사용하는 경우 RUM 가져오기만 변경하면 되며, 프레임워크 플러그인 구성은 그대로 유지됩니다.
다음 예제는 공용 OpenWay의 site와 clientToken을 사용합니다. DataKit 직접 연결을 사용하는 경우
이 두 매개변수를 datakitOrigin으로 대체하고, 두 가지 업로드 주소를 동시에 구성하지 마십시오.
React¶
설치¶
React Router¶
Router 통합을 활성화하려면 다음이 필요합니다.
reactPlugin()에서router: true를 설정합니다.- React Router 메인 버전과 일치하는 플러그인 하위 경로에서 Router 생성 API,
Routes또는useRoutes를 가져옵니다.
다음 예제는 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} />)
Router 버전에 따라 진입점을 선택하십시오.
| Router | 플러그인 진입점 | 플러그인 진입점에서 내보내는 API |
|---|---|---|
| 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 |
동일 |
| React Router 8 | @cloudcare/browser-rum-react/react-router-v8 |
동일 |
| TanStack Router 1.x | @cloudcare/browser-rum-react/tanstack-router |
createRouter |
다른 Router API는 애플리케이션에 설치된 Router 패키지에서 가져옵니다. 프레임워크 플러그인 메인 진입점에서 Router wrapper를 가져오지 마십시오. 그렇지 않으면 플러그인이 Router 메인 버전을 구분할 수 없습니다.
React 오류¶
애플리케이션 루트 노드 또는 주요 비즈니스 영역 외부에 ErrorBoundary를 사용하십시오.
import { ErrorBoundary } from "@cloudcare/browser-rum-react"
root.render(
<ErrorBoundary
fallback={({ resetError }) => (
<button type="button" onClick={resetError}>재시도</button>
)}
context={{ module: "checkout" }}
>
<App />
</ErrorBoundary>
)
이미 ErrorBoundary, React 19 루트 노드 오류 콜백 또는 비즈니스에서 직접 오류를 캡처하는 경우
addReactError(error, errorInfo, context)를 호출하십시오. React Error 이벤트에는
context.framework = react가 포함되며, 컴포넌트 스택이 있는 경우
context.component_stack도 포함됩니다.
Vue¶
설치¶
Vue 3 및 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")
app을 전달하면 플러그인이 Vue 전역 오류 핸들러를 설치하며, 애플리케이션에 이미 존재하는
app.config.errorHandler도 그대로 유지됩니다.
Vue 2.7 및 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")
이미 사용자 정의 오류 핸들러가 있는 경우 addVueError(error, componentInstance, info, context)를
호출할 수도 있습니다. Vue Error 이벤트에는 context.framework = vue가 포함되며,
가능한 경우 컴포넌트 이름과 컴포넌트 경로가 기록됩니다.
Angular¶
설치¶
Standalone 애플리케이션¶
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()는 Angular Router가 NavigationEnd를 성공적으로 트리거한 후에만 View를 시작합니다.
취소되거나 실패한 네비게이션은 View를 생성하지 않습니다. provideRumErrorHandler()는 Error를 업로드하는 동시에,
Angular 기본 콘솔 오류 처리 동작을 유지합니다.
이미 사용자 정의 ErrorHandler가 있는 경우 addAngularError(error, context)를 호출할 수 있습니다.
이미 사용자 정의 Router 통합이 있는 경우 trackAngularRouter(router)를 호출할 수 있습니다.
View 이름 지정 및 생명주기¶
프레임워크 Router 통합을 활성화하면 플러그인이 수동 View를 관리합니다.
| 시나리오 | 수집 동작 |
|---|---|
| 라우팅 최초 진입 | 초기 View 생성 |
| pathname 변경 및 네비게이션 성공 | 새 View 생성 |
| query 변경만 있는 경우 | 새 View 생성 안 함 |
| hash 변경만 있는 경우 | React, Angular는 새 View 생성 안 함; Nuxt는 hash 라우팅 추적 가능 |
| 동적 라우팅 | /users/:id, /users/[id] 등 템플릿 이름 사용 |
| 이동 취소, 실패 또는 새 페이지 미제출 | View 생성 안 함 |
동일한 라우팅을 추적하기 위해 Router 플러그인과 비즈니스 코드의 datafluxRum.startView()를 동시에 사용하지 마십시오.
그렇지 않으면 중복 View가 생성될 수 있습니다.
React, Vue 및 Angular 플러그인은 모두 getViewName 콜백을 지원합니다. 사용자 정의 문자열을 반환하면 기본
라우팅 템플릿을 재정의할 수 있습니다. undefined를 반환하면 현재 라우팅의 View 생성을 건너뜁니다.
연동 확인¶
- 브라우저 개발자 도구를 열고 Network에서
/v1/write/rum을 필터링합니다. /users/1에서/users/2로 이동하는 등 동적 라우팅으로 진입합니다.- View 이름이 특정 사용자 ID가 아닌 라우팅 템플릿으로 유지되는지 확인합니다.
- query만 수정하고 View가 중복 생성되지 않는지 확인합니다.
- 프레임워크 렌더링 오류를 트리거하고
type=error가 나타나고 해당하는context.framework가 함께 표시되는지 확인합니다.
자주 묻는 질문¶
router: true를 활성화했지만 View가 없습니다.¶
Router 생성 API, Routes 또는 useRoutes가 현재 Router 메인 버전과 일치하는
플러그인 하위 경로에서 가져왔는지 확인하십시오. 플러그인을 등록했지만 원래의 Router 생성 API를 계속 사용하는 경우
플러그인이 전체 라우팅 상태를 가져올 수 없습니다.
하나의 라우팅 이동으로 여러 View가 생성됩니다.¶
Router 플러그인이 중복 등록되지 않았는지, 동일한 라우팅 변경에 대해 datafluxRum.startView()가
추가로 호출되지 않았는지 확인하십시오.
동적 라우팅에서 많은 View 이름이 생성됩니다.¶
Router 템플릿 경로를 우선적으로 사용하십시오. 라우팅 구성에서 안정적인 이름을 자동으로 얻을 수 없는 경우
getViewName을 통해 엔터티 ID를 고정된 비즈니스 이름으로 통일하십시오.