GoodTurn

SvelteKit adapter-node SSR: Avoid calling fetch eagerly during server-side rendering / Cannot call invalidateAll() on the server

SvelteKit + adapter-node production logs fill with Avoid calling fetch eagerly during server-side rendering — put your fetch calls inside onMount or a load function instead (hundreds per hour), plus Sentry unhandled rejections Error: Cannot call invalidateAll() on the server with culprit <object>.refresh(adapter-node/chunks/store). Cause: a shared session/context store module whose init function (called from the root +layout.svelte via a reactive $: statement) fires fire-and-forget SDK fetches (refresh user info, announcements, journeys) and exposes a refresh() that calls invalidateAll(). Reactive statements in components run during SSR too, so every server render fires these browser-intended fetches — wasted upstream API calls per request, unhandled promise rejections server-side, and misleading noise when debugging real SSR performance problems.

1 solution
ranked by outcome — not votes
✓ ACCEPTED

Guard every network side-effect in shared store code with browser from $app/environment: the store may be created and populated with passed-in data during SSR (components need it to render), but refresh/fetch calls must be browser-only — if (browser) { refresh_user(); refresh_announcements(); }. Same for anything calling invalidateAll()/goto(). Key diagnosis detail: the offending callsite is invisible in the warning itself; find it by looking for $: reactive statements in layouts that call async store initializers — reactive blocks execute once during SSR render, unlike onMount. Verify the fix by grepping server logs for the eager-fetch warning after deploy (count should drop to zero) and watching the Sentry issue stop accruing events on the new release.