feat(vue,nuxt): Record default UI spans without Options API (mixins) - #24174
feat(vue,nuxt): Record default UI spans without Options API (mixins)#24174s1gr1d wants to merge 2 commits into
Conversation
|
bugbot run |
size-limit report 📦
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7b3c0ee. Configure here.
| // page's `<Suspense>` boundary resolves. Both hooks are no-ops on the mixin path (Options | ||
| // API enabled), which keeps its historical span boundaries. | ||
| nuxtApp.hook('app:suspense:resolve', () => INTERNAL_extendVueRootRenderSpan(vueApp)); | ||
| nuxtApp.hook('page:finish', () => INTERNAL_extendVueRootRenderSpan(vueApp)); |
There was a problem hiding this comment.
page:finish reopens root render span
Medium Severity
page:finish runs on every client navigation, and INTERNAL_extendVueRootRenderSpan only no-ops after $_sentryRootComponentSpan is cleared. A navigation inside the debounce window still sees that span, resets the timer, and moves Application Render's end timestamp onto the next page. Fast clicks and navigateTo redirects inflate the pageload child and can end it after the pageload parent.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7b3c0ee. Configure here.
There was a problem hiding this comment.
Not reproducible, but hardened anyway (and added a test).
A navigation ends the pageload idle span before the next page's page:finish
fires.
What was true: the guard only checked that the span reference exists, so the first post-navigation page:finish armed one dead timer. It now checks span.isRecording() and drops stale references, with a regression test.


Nuxt 5 disables Vue's Options API by default (nuxt/nuxt#35791). That turns
app.mixin()into a silent no-op, and every Vue UI span comes from that mixin:Application RenderandVue <Root>disappear with no signal.When the mixin is dropped, the SDK now wraps
app.mount()and calls the same mixin hook bodies, so the default spans stay identical. The Nuxt SDK additionally extends the root span until<Suspense>resolves.trackComponentsstill needs the Options API and warns when it is lost. Vue 2 behavior stays unchanged (always needs Options API as it's not possible otherwise).Closes #23375
Docs follow-up: getsentry/sentry-docs#19290