Skip to content

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

Merged
s1gr1d merged 1 commit into
developfrom
sig/sveltekit-cache-components
Nov 11, 2026
Merged

s1gr1d merged 1 commit into
developfrom
sig/sveltekit-cache-components

Conversation

@s1gr1d

@s1gr1d s1gr1d commented Nov 11, 2026

Copy link
Copy Markdown
Member

Why: Pageloads of pages prerendered during vite build look like they have no server instrumentation. Now these pages get an empty sentry-cache-origin meta tag, and the pageload gets page.server_rendering.type: static. Unlike Next.js (#25318), the pageload gets no link, because the SDK does not reliably send spans from the build.

Unsure about: To leave out ssr = false shells, the server checks for node_ids: in Kit's boot script, which Kit writes only for server-rendered pages (source).

Example (with UI changes from getsentry/sentry#130771 applied) or pre-rendered, static page: https://sentry-4x3dkn58u.sentry.dev/explore/traces/trace/97190404f66048bd89da29cc0a21304f/

image

Linear: JSSDK-37

@s1gr1d
s1gr1d requested review from a team, JPeer264 and stephanie-anderson November 11, 2026 14:18
@s1gr1d
s1gr1d requested a review from a team as a code owner November 11, 2026 14:18
@github-actions

Copy link
Copy Markdown
Contributor

size-limit report 📦

Compared: f4bd435 (PR test merge using develop at 187ee90)

Against: 187ee90 (develop) · base run #65693

✅ Baseline matches: this diff contains only this PR's changes.

Path Size % Change Change
@sentry/browser 29.98 kB - -
@sentry/browser - with treeshaking flags 28.13 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 28.02 kB - -
@sentry/browser (incl. Tracing) 52.36 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 52.36 kB - -
@sentry/browser (incl. Tracing, Profiling) 55.33 kB - -
@sentry/browser (incl. Tracing, Replay) 92.76 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 81.41 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 97.49 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 110.48 kB - -
@sentry/browser (incl. Feedback) 47.57 kB - -
@sentry/browser (incl. sendFeedback) 35.07 kB - -
@sentry/browser (incl. FeedbackAsync) 40.18 kB - -
@sentry/browser (incl. Metrics) 31.54 kB - -
@sentry/browser (incl. Logs) 31.83 kB - -
@sentry/browser (incl. Metrics & Logs) 32.52 kB - -
@sentry/react 31.84 kB - -
@sentry/react (incl. Tracing) 54.8 kB - -
@sentry/vue 38.39 kB - -
@sentry/vue (incl. Tracing) 55.38 kB - -
@sentry/svelte 30 kB - -
@sentry/remix (Remix 3 client bundle) 57.97 kB - -
CDN Bundle 31.77 kB - -
CDN Bundle (incl. Tracing) 52.94 kB - -
CDN Bundle (incl. Logs, Metrics) 34.58 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 55.45 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 76.05 kB - -
CDN Bundle (incl. Tracing, Replay) 91.22 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 93.77 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 97.34 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 99.93 kB - -
CDN Bundle - uncompressed 92.89 kB - -
CDN Bundle (incl. Tracing) - uncompressed 156.15 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 101.42 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 163.92 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 233.31 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 278.17 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 285.93 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 291.87 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 299.63 kB - -
@sentry/nextjs (client) 57.74 kB - -
@sentry/sveltekit (client) 52.92 kB +0.09% +46 B 🔺
@sentry/core/server 44.51 kB - -
@sentry/core/browser 14.02 kB - -
@sentry/node 157.81 kB +0.01% +15 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 82.31 kB - -
@sentry/node - without tracing 97.24 kB +0.02% +19 B 🔺
@sentry/node - without channel injection 138.13 kB +0.02% +19 B 🔺
@sentry/aws-serverless 106.09 kB +0.03% +24 B 🔺
@sentry/cloudflare (withSentry) - minified 204.45 kB - -
@sentry/cloudflare (withSentry) 508.11 kB - -
@sentry/nextjs/cloudflare (withSentry) - minified 229.47 kB - -

View base workflow run

@s1gr1d
s1gr1d merged commit f8eb545 into develop Nov 11, 2026
61 checks passed
@s1gr1d
s1gr1d deleted the sig/sveltekit-cache-components branch November 11, 2026 14:46
s1gr1d added a commit that referenced this pull request Nov 13, 2026
**Why:** Visitors of a Nuxt page cached by a route rule (`cache`, `swr`,
`isr` on Vercel/Netlify) continued the server trace of the request that
rendered it. Like Next.js (#25318) and SvelteKit (#26301), these pages
now get a `sentry-cache-origin` meta tag in place of the trace tags. The
pageload is `static` and links the render if it was sampled. `isr` only
counts as cached on presets with a platform cache: on `node-server`,
Nitro renders `isr` pages per request. Tested on a Vercel deploy.





**How to review:** Start with `runtime/utils/pageMetaTags.ts` (server
decision) and `runtime/utils/cacheOriginPageload.ts` (pageload).

**Unsure about:** `withCacheOrigin` now exists in Next.js, SvelteKit and
Nuxt. I plan to share it from `@sentry/browser` in a follow-up.


Example with the UI changes from
getsentry/sentry#130771
<img width="1374" height="390" alt="image"
src="https://github.com/user-attachments/assets/d066316e-63ec-44ba-8105-3acdbeb46fe7"
/>


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


Linear: [JSSDK-36
](https://linear.app/getsentry/issue/JSSDK-36/nuxt-rendering-modes)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
s1gr1d added a commit that referenced this pull request Nov 13, 2026
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):
<img width="1378" height="418" alt="image"
src="https://github.com/user-attachments/assets/842594fd-38cc-418f-b981-369da8305375"
/>



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


Linear:
[JSSDK-37](https://linear.app/getsentry/issue/JSSDK-37/sveltekit-page-options)
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