Skip to content

feat(sveltekit): Mark pageloads of prerendered pages - #26307

Open
s1gr1d wants to merge 3 commits into
developfrom
sig/sveltekit-vercel-isr
Open

s1gr1d wants to merge 3 commits into
developfrom
sig/sveltekit-vercel-isr

Conversation

@s1gr1d

@s1gr1d s1gr1d commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Stacked on #26301.

Why: Vercel ISR (config.isr) caches the HTML of one request and serves it to every visitor until it expires. That HTML holds the live sentry-trace and baggage tags of the render, so every visitor continued the same old server trace. Next.js had the same bug, fixed in #25141. Now a page that Vercel renders for its ISR cache gets a sentry-cache-origin tag with the render's sentry-trace in place of the trace tags. The pageload starts its own trace, gets page.server_rendering.type: static, and links the render with a cache_origin link, as in Next.js (#25318).

To detect an ISR render, sentryHandle reads the x-vercel-isr request header. Vercel sends it to every invocation of an ISR function, also for background revalidations and for routes that get config.isr from a layout. The adapter's own __pathname marker is gone before Kit sees the request, and handle cannot see the route config (tested both on a Vercel deployment).

Like a use cache hit, the pageload links only a sampled render. An unsampled render still marks the pageload as static. A page with ssr = false gets no tags, as in the build.

How to review: Start with getCacheOrigin in handle.ts. It returns the render's trace (ISR), '' (build) or undefined (rendered for this request only). Then withCacheOrigin in client/traceMetaTags.ts. The two browser-tracing variants only wrap their existing span options.

Unsure about: A client can send x-vercel-isr to a normal SSR route, and the function sees it. That only changes the pageload of the request that sends it: it links its own server request instead of continuing it. I think that is acceptable. I did not check draft mode (bypassToken), where Vercel does not cache the render.

Example with the UI changes from getsentry/sentry#130771 (a visitor that got an already happened ISR render):
image

https://sentry-4x3dkn58u.sentry.dev/explore/traces/trace/63b1dbe5fe3849f2b13df81530857c03/

Linear: JSSDK-37

@s1gr1d
s1gr1d requested review from a team, JPeer264 and msonnb November 11, 2026 15:45
@s1gr1d
s1gr1d requested a review from a team as a code owner November 11, 2026 15:45
@s1gr1d
s1gr1d requested a review from chargome November 11, 2026 15:48
@s1gr1d

s1gr1d commented Nov 11, 2026

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 395abdb. Configure here.

return getTraceMetaTags();
}
return isServerRenderedPage(html) ? `<meta name="${CACHE_ORIGIN_META_TAG_NAME}" content=""/>` : '';
return isServerRenderedPage(html) ? `<meta name="${CACHE_ORIGIN_META_TAG_NAME}" content="${cacheOrigin}"/>` : '';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what does a '' cache origin mean? 🤔 I wonder if we can simplify this a bit, I always find it a bit hard to follow if something can deliberately return '' or undefined 🤔

This branch has not been deployed

No deployments
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