Skip to content

fix(vue): Make pageload span handling more reliable #16799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

mydea
Copy link
Member

@mydea mydea commented Jul 3, 2025

We used to rely on a somewhat complex heuristic to determine if a router change is a pageload or not. This somehow did not work anymore here: #16783 in nuxt-3-min. Likely some vue router difference... However, I think this can be simplified anyhow, by just checking if we have an active pageload span. That seems to work reliably enough.

cursor[bot]

This comment was marked as outdated.

Copy link
Contributor

github-actions bot commented Jul 3, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 23.99 kB - -
@sentry/browser - with treeshaking flags 23.76 kB - -
@sentry/browser (incl. Tracing) 39.59 kB - -
@sentry/browser (incl. Tracing, Replay) 77.69 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 70.78 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 82.45 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 94.57 kB - -
@sentry/browser (incl. Feedback) 40.75 kB - -
@sentry/browser (incl. sendFeedback) 28.7 kB - -
@sentry/browser (incl. FeedbackAsync) 33.59 kB - -
@sentry/react 25.76 kB - -
@sentry/react (incl. Tracing) 41.58 kB - -
@sentry/vue 28.37 kB - -
@sentry/vue (incl. Tracing) 41.37 kB -0.08% -33 B 🔽
@sentry/svelte 24.01 kB - -
CDN Bundle 25.5 kB - -
CDN Bundle (incl. Tracing) 39.6 kB - -
CDN Bundle (incl. Tracing, Replay) 75.5 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 80.96 kB - -
CDN Bundle - uncompressed 74.5 kB - -
CDN Bundle (incl. Tracing) - uncompressed 117.63 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 231.68 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 244.5 kB - -
@sentry/nextjs (client) 43.22 kB - -
@sentry/sveltekit (client) 40.04 kB - -
@sentry/node 162.03 kB +0.01% +1 B 🔺
@sentry/node - without tracing 98.64 kB - -
@sentry/aws-serverless 124.4 kB -0.01% -1 B 🔽

View base workflow run

mydea added 2 commits July 3, 2025 13:58
We used to rely on a somewhat complex heuristic to determine if a router change is a pageload or not. This somehow did not work anymore here: #16783 in nuxt-3-min. Likely some vue router difference... However, I think this can be simplified anyhow, by just checking if we have an active pageload span. That seems to work reliably enough.
@mydea mydea force-pushed the fn/vue-pageload-reliable branch from cc59c02 to 43a5fa0 Compare July 3, 2025 12:01
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: Page Load Detection Fails on Subsequent Loads

The new pageload detection logic incorrectly handles page loads. The hasHandledFirstPageLoad flag, once set, prevents getActivePageLoadSpan() from being called, causing all subsequent legitimate page loads (e.g., hard refreshes) to be incorrectly treated as navigation events. Additionally, if no active pageload span exists during the initial route resolution, the first page load may also be incorrectly classified as a navigation. This results in incorrect transaction types ('navigation' instead of 'pageload') and missed updates for pageload spans. Furthermore, if the hasHandledFirstPageLoad flag is never set (e.g., if pageload instrumentation is disabled or no initial pageload span exists), getActivePageLoadSpan() is inefficiently called on every subsequent navigation.

packages/vue/src/router.ts#L58-L106

// We avoid trying to re-fetch the page load span when we know we already handled it the first time
const activePageLoadSpan = !hasHandledFirstPageLoad ? getActivePageLoadSpan() : undefined;
const attributes: SpanAttributes = {};
for (const key of Object.keys(to.params)) {
attributes[`params.${key}`] = to.params[key];
}
for (const key of Object.keys(to.query)) {
const value = to.query[key];
if (value) {
attributes[`query.${key}`] = value;
}
}
// Determine a name for the routing transaction and where that name came from
let spanName: string = to.path;
let transactionSource: TransactionSource = 'url';
if (to.name && options.routeLabel !== 'path') {
spanName = to.name.toString();
transactionSource = 'custom';
} else if (to.matched.length > 0) {
const lastIndex = to.matched.length - 1;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
spanName = to.matched[lastIndex]!.path;
transactionSource = 'route';
}
getCurrentScope().setTransactionName(spanName);
// Update the existing page load span with parametrized route information
if (options.instrumentPageLoad && activePageLoadSpan) {
const existingAttributes = spanToJSON(activePageLoadSpan).data;
if (existingAttributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] !== 'custom') {
activePageLoadSpan.updateName(spanName);
activePageLoadSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, transactionSource);
}
// Set router attributes on the existing pageload transaction
// This will override the origin, and add params & query attributes
activePageLoadSpan.setAttributes({
...attributes,
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.vue',
});
hasHandledFirstPageLoad = true;
}
if (options.instrumentNavigation && !activePageLoadSpan) {

Fix in Cursor


Bug: Page Load Flag Fails, Navigation Spans Mismanaged

The hasHandledFirstPageLoad flag is not reliably set to true after the initial page load, causing getActivePageLoadSpan() to be called on every subsequent navigation and defeating optimization. This occurs because the flag is only updated if options.instrumentPageLoad is true and an active pageload span exists. Consequently, the !activePageLoadSpan check can also incorrectly prevent navigation spans from being created when options.instrumentNavigation is true but options.instrumentPageLoad is false, as an active pageload span might still be present.

packages/vue/src/router.ts#L88-L106

// Update the existing page load span with parametrized route information
if (options.instrumentPageLoad && activePageLoadSpan) {
const existingAttributes = spanToJSON(activePageLoadSpan).data;
if (existingAttributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] !== 'custom') {
activePageLoadSpan.updateName(spanName);
activePageLoadSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, transactionSource);
}
// Set router attributes on the existing pageload transaction
// This will override the origin, and add params & query attributes
activePageLoadSpan.setAttributes({
...attributes,
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.vue',
});
hasHandledFirstPageLoad = true;
}
if (options.instrumentNavigation && !activePageLoadSpan) {

Fix in Cursor


Was this report helpful? Give feedback by reacting with 👍 or 👎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants