Skip to content

⚗️ add Vue Router v4 view tracking#4328

Merged
mormubis merged 11 commits intomainfrom
adlrb/vue-router
Mar 25, 2026
Merged

⚗️ add Vue Router v4 view tracking#4328
mormubis merged 11 commits intomainfrom
adlrb/vue-router

Conversation

@mormubis
Copy link
Copy Markdown
Contributor

@mormubis mormubis commented Mar 13, 2026

Motivation

After this PR, navigating between routes in a Vue app automatically creates RUM views with parameterized names instead of raw URLs. It also improves the component_stack in Vue error tracking to include the full parent component hierarchy rather than just the component name.

Changes

Exports a wrapped createRouter from @datadog/browser-rum-vue/vue-router-v4 as a drop-in for the standard vue-router import:

import { createRouter } from '@datadog/browser-rum-vue/vue-router-v4'

On each navigation, afterEach calls startView() with the parameterized route name (/users/:id rather than /users/42). Failed navigations (blocked by guards, cancelled, duplicated) and query-only changes are filtered out.

component_stack now walks the ComponentInternalInstance parent chain to build the full hierarchy, matching what Vue DevTools shows.

The PR includes a vue-router-app test app and E2E tests for both features.

Requires vuePlugin({ router: true }) alongside this import. That sets trackViewsManually: true at init so the SDK's built-in URL tracking does not race with the router integration.

Test instructions

yarn test:unit --spec packages/rum-vue/src/domain/router/startVueRouterView.spec.ts
yarn test:unit --spec packages/rum-vue/src/domain/router/vueRouter.spec.ts
yarn test:e2e:init
yarn test:e2e -g "vue plugin"

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

// afterEach fires for the initial navigation when the app is mounted via app.use(router).
// In tests without mounting, an explicit router.push() is needed to trigger the hook.
router.afterEach((to, _from, failure) => {
if (failure && !isNavigationFailure(failure, NavigationFailureType.duplicated)) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vue Router's afterEach fires even for navigations blocked by a guard, not just successful ones. The failure parameter tells you why. We skip cancelled (preempted by another navigation) and aborted (guard explicitly blocked it). duplicated (same route you're already on) we let through - that's not really a failure, the URL just didn't change because it was already there.

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da bot commented Mar 16, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 176.56 KiB 176.56 KiB 0 B 0.00%
Rum Profiler 6.16 KiB 6.16 KiB 0 B 0.00%
Rum Recorder 27.46 KiB 27.46 KiB 0 B 0.00%
Logs 56.88 KiB 56.88 KiB 0 B 0.00%
Rum Slim 132.19 KiB 132.19 KiB 0 B 0.00%
Worker 23.63 KiB 23.63 KiB 0 B 0.00%
🚀 CPU Performance
Action Name Base CPU Time (ms) Local CPU Time (ms) 𝚫%
RUM - add global context 0.0038 0.0041 +7.89%
RUM - add action 0.0128 0.014 +9.37%
RUM - add error 0.0128 0.0168 +31.25%
RUM - add timing 0.0025 0.0027 +8.00%
RUM - start view 0.0119 0.0124 +4.20%
RUM - start/stop session replay recording 0.0007 0.0008 +14.29%
Logs - log message 0.0141 0.0147 +4.26%
🧠 Memory Performance
Action Name Base Memory Consumption Local Memory Consumption 𝚫
RUM - add global context 26.92 KiB 26.61 KiB -316 B
RUM - add action 51.58 KiB 51.65 KiB +73 B
RUM - add timing 26.27 KiB 26.96 KiB +709 B
RUM - add error 56.09 KiB 55.58 KiB -513 B
RUM - start/stop session replay recording 26.11 KiB 26.70 KiB +600 B
RUM - start view 460.15 KiB 463.37 KiB +3.22 KiB
Logs - log message 44.22 KiB 44.58 KiB +375 B

🔗 RealWorld

@datadog-official
Copy link
Copy Markdown

datadog-official bot commented Mar 16, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 70.27%
Overall Coverage: 77.27% (-0.04%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 543ef1c | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@mormubis mormubis force-pushed the adlrb/vue-plugin branch 4 times, most recently from 3a8e944 to 8c710e0 Compare March 18, 2026 08:46
Base automatically changed from adlrb/vue-plugin to main March 18, 2026 16:03
@mormubis mormubis marked this pull request as ready for review March 19, 2026 15:28
@mormubis mormubis requested a review from a team as a code owner March 19, 2026 15:28
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ce5ece0d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@mormubis mormubis marked this pull request as draft March 20, 2026 10:16
@mormubis mormubis force-pushed the adlrb/vue-router branch 2 times, most recently from aaa50ac to 90c0728 Compare March 20, 2026 10:54
return this
}

withVueApp() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could reuse the repeated code with nextjs here?

- replace @vue/test-utils usage with manual mocks in addVueError.spec.ts to avoid Object.fromEntries incompatibility on Chrome 63
- add @vue/test-utils to swc transpilation list in karma.base.conf.js for older browser compat
- add host: true to vue-router-app vite config to fix E2E ERR_CONNECTION_REFUSED
Remove strictPort from vite.config.ts and switch from a hardcoded url
to wait.stdout with a named capture group, consistent with how the
nextjs app is configured.
Vite wraps 'Local' in ANSI bold codes when FORCE_COLOR is set, breaking
the regex. Setting NO_COLOR=1 in the webServer env disables that.
…rors

Edge reports a missing /favicon.ico as a console.error, which trips the
E2E teardown check. Adding an empty data: favicon prevents the request.
… with React

Also aligns computeViewName tests to cases.forEach() format and adds a
catch-all route test case documenting the /:pathMatch(.*)*  behavior.
@rgaignault rgaignault self-requested a review March 24, 2026 14:06
@mormubis mormubis changed the title ✨ add Vue Router v4 view tracking ⚗️ add Vue Router v4 view tracking Mar 24, 2026
Copy link
Copy Markdown
Contributor

@BeltranBulbarellaDD BeltranBulbarellaDD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@mormubis mormubis marked this pull request as ready for review March 25, 2026 08:58
@mormubis mormubis merged commit 13704f3 into main Mar 25, 2026
18 checks passed
@mormubis mormubis deleted the adlrb/vue-router branch March 25, 2026 09:51
@github-actions github-actions bot locked and limited conversation to collaborators Mar 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants