Skip to content

Commit c098258

Browse files
msonnbclaude
andcommitted
feat(vue): Set navigation.route.id from the Vue Router route name
Sets the navigation.route.id attribute (from @sentry/conventions) on pageload and navigation spans, sourced from the Vue Router route name (to.name). This is the framework-assigned route identifier, which Relay prefers over url.template for span description inference. The attribute is set independently of the routeLabel option: routeLabel only controls the span name/source, whereas the route id identifies the route regardless. This is most valuable when to.name drives the span (source 'custom'), where url.template is not set today, so navigation.route.id becomes the only structured route identifier. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6ff1b4d commit c098258

3 files changed

Lines changed: 16 additions & 2 deletions

File tree

dev-packages/e2e-tests/test-applications/vue-3/tests/performance.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ test('sends a pageload transaction with a route name as transaction name if avai
120120
'sentry.source': 'custom',
121121
'sentry.origin': 'auto.pageload.vue',
122122
'sentry.op': 'pageload',
123+
'navigation.route.id': 'AboutView',
123124
'url.path': '/about',
124125
'url.full': expect.stringMatching(/^https?:\/\/localhost:\d+\/about$/),
125126
},

packages/vue/src/router.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { captureException, getAbsoluteUrl } from '@sentry/browser';
2-
import { PARAMS_KEY_BASE, URL_PATH_PARAMETER_KEY_BASE, URL_TEMPLATE } from '@sentry/conventions/attributes';
2+
import {
3+
NAVIGATION_ROUTE_ID,
4+
PARAMS_KEY_BASE,
5+
URL_PATH_PARAMETER_KEY_BASE,
6+
URL_TEMPLATE,
7+
} from '@sentry/conventions/attributes';
38
import type { Span, SpanAttributes, StartSpanOptions, TransactionSource } from '@sentry/core';
49
import {
510
getActiveSpan,
@@ -101,6 +106,10 @@ export function instrumentVueRouter(
101106
attributes[URL_TEMPLATE] = spanName;
102107
}
103108

109+
if (to.name) {
110+
attributes[NAVIGATION_ROUTE_ID] = to.name.toString();
111+
}
112+
104113
getCurrentScope().setTransactionName(spanName);
105114

106115
// Update the existing page load span with parametrized route information

packages/vue/test/router.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as SentryBrowser from '@sentry/browser';
22
import type { Span, SpanAttributes } from '@sentry/core';
33
import * as SentryCore from '@sentry/core';
44
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
5-
import { URL_TEMPLATE } from '@sentry/conventions/attributes';
5+
import { NAVIGATION_ROUTE_ID, URL_TEMPLATE } from '@sentry/conventions/attributes';
66
import { afterEach, describe, expect, it, vi } from 'vitest';
77
import type { Route } from '../src/router';
88
import { instrumentVueRouter } from '../src/router';
@@ -465,5 +465,9 @@ function getAttributesForRoute(route: Route, urlTemplate?: string): SpanAttribut
465465
attributes[URL_TEMPLATE] = urlTemplate;
466466
}
467467

468+
if (route.name) {
469+
attributes[NAVIGATION_ROUTE_ID] = route.name.toString();
470+
}
471+
468472
return attributes;
469473
}

0 commit comments

Comments
 (0)