Repository navigation
Description
Is there an existing issue for this?
- I have checked for existing issues
How do you use Sentry?
Sentry SaaS (sentry.io)
Which SDK are you using?
@sentry/sveltekit
SDK Version
11.8.0 (the same code is in 11.11.0)
Framework Version
@sveltejs/kit 3.1.0, svelte 5.57.2
Description
With browser tracing on, instrumentSvelteKitTracing (packages/sveltekit/src/client/svelte5BrowserTracing.ts) replaces window.fetch with a wrapper that calls getCurrentNavigation() before every request:
WINDOW.fetch = (...args) => {
const navigation = getCurrentNavigation();
if (navigation) _startNavigation(navigation);
return originalFetch(...args);
};getCurrentNavigation() (packages/sveltekit/src/client/navigationState.svelte.ts) reads navigating.type, navigating.from and the other fields from $app/state. Those are reactive reads, and they aren't untracked. When the app calls fetch synchronously inside a $effect, which is the usual pattern, Svelte records navigating as a dependency of that effect. The effect then re-runs, and repeats its requests, when any navigation starts and again when it completes.
In practice:
- leaving a page re-sends that page's data requests as the user navigates away (the results are thrown away);
- a navigation that stays on the same route (e.g. only the query string changes) sends every effect-driven request twice.
None of this happens with Sentry disabled. The SvelteKit 2 / Svelte 4 path (svelte4BrowserTracing.ts, store subscriptions) isn't affected. The SvelteKit 3 path came in with #22264.
Reproduction Example/SDK Setup
// src/hooks.client.js
import * as Sentry from '@sentry/sveltekit';
Sentry.init({
dsn: '...',
integrations: [Sentry.browserTracingIntegration()],
tracesSampleRate: 1
});<!-- src/routes/a/+page.svelte -->
<script>
let n = $state(0);
$effect(() => {
fetch('/api/ping').then(() => n++); // called synchronously in the effect
});
</script>
<p>requests: {n}</p>
<a href="/b">go to b</a>
<a href="/a?x=1">same route, new query</a>Steps to Reproduce
- Open
/a. One request to/api/ping. - Click "same route, new query". Two more requests (navigation start and navigation end).
- Click "go to b".
/api/pingis requested again while the page is being left.
Putting $inspect.trace() inside the effect lists $state navigation (SvelteKit's internal state behind navigating) as the changed dependency on those re-runs.
Expected Result
Instrumenting fetch doesn't change the calling code's reactive dependencies: the effect runs once and re-runs only when its own inputs change.
Actual Result
Every effect that calls fetch before its first await re-runs on every navigation, the one leaving the page included.
Suggested fix
Read the navigation untracked, e.g. in navigationState.svelte.ts:
import { untrack } from 'svelte';
export function getCurrentNavigation() {
return untrack(_snapshot);
}(or wrap the getCurrentNavigation() call inside the fetch wrapper in untrack).
Workaround
In hooks.client.ts, after Sentry.init:
import { untrack } from 'svelte';
const sentryFetch = window.fetch;
window.fetch = (...args) => untrack(() => sentryFetch(...args));Metadata
Metadata
Assignees
Projects
- StatusShow more project fieldsNo status
Activity
linear-code commentedon Nov 5, 2026
JS-4071
chargome commentedon Nov 5, 2026
Thanks for reporting!
fix(sveltekit): Read navigation untracked in the Kit 3 fetch wrapper (g…
fix(sveltekit): Read navigation untracked in the Kit 3 fetch wrapper (g…
github-actions commentedon Nov 10, 2026
A PR closing this issue has just been released 🚀
This issue was referenced by PR #26136, which was included in the 11.12.0 release.