Describe the bug
On 3.0.0-next.8, calling redirect() in a server load/hook throws ReferenceError: window is not defined when deployed to a non-Node server runtime (Cloudflare Workers / workerd). This breaks every server-side redirect.
The "forbid external redirects by default" change (#16198) added validate_redirect_location() → is_external_location(), which calls get_origin() unconditionally:
// packages/kit/src/exports/url.js
export function is_external_location(location) {
const origin = get_origin(); // <-- always called
try {
return !matches_external_allowlist_entry(location, origin ?? REDIRECT_BASE);
} catch { return true; }
}
In the Cloudflare/worker server bundle, get_origin resolves to the browser implementation instead of the server one:
// packages/kit/src/exports/internal/client.js
export function get_origin() {
return window.location.origin; // <-- no `window` on workerd
}
(there is a server version at packages/kit/src/exports/internal/server/index.js). On workerd there is no window, so it throws — and because get_origin() is called before the try/catch, the ReferenceError propagates out of redirect().
Reproduction
@sveltejs/[email protected] + @sveltejs/adapter-cloudflare, deployed to Cloudflare Workers. Any server load with an internal redirect(302, '/somewhere') → 500 on every request.
Logs
ReferenceError: window is not defined
at get_origin (_worker.js:583:3)
at is_external_location (_worker.js:1274:19)
at validate_redirect_location (_worker.js:1289:8)
at redirect (_worker.js:1353:3)
at load (...)
Expected
Server-side redirect() should use the server get_origin (or a request-derived origin / just REDIRECT_BASE) rather than window.location.origin, so redirects work on non-browser server runtimes (workerd, Deno, etc.).
Severity
Breaks all server-side redirects on non-Node runtimes.
System
@sveltejs/kit: 3.0.0-next.8
@sveltejs/adapter-cloudflare: 7.2.9
- Vite 8, Svelte 5
- Runtime: Cloudflare Workers (workerd)
Describe the bug
On
3.0.0-next.8, callingredirect()in a serverload/hook throwsReferenceError: window is not definedwhen deployed to a non-Node server runtime (Cloudflare Workers / workerd). This breaks every server-side redirect.The "forbid external redirects by default" change (#16198) added
validate_redirect_location()→is_external_location(), which callsget_origin()unconditionally:In the Cloudflare/worker server bundle,
get_originresolves to the browser implementation instead of the server one:(there is a server version at
packages/kit/src/exports/internal/server/index.js). On workerd there is nowindow, so it throws — and becauseget_origin()is called before thetry/catch, theReferenceErrorpropagates out ofredirect().Reproduction
@sveltejs/[email protected]+@sveltejs/adapter-cloudflare, deployed to Cloudflare Workers. Any serverloadwith an internalredirect(302, '/somewhere')→ 500 on every request.Logs
Expected
Server-side
redirect()should use the serverget_origin(or a request-derived origin / justREDIRECT_BASE) rather thanwindow.location.origin, so redirects work on non-browser server runtimes (workerd, Deno, etc.).Severity
Breaks all server-side redirects on non-Node runtimes.
System
@sveltejs/kit:3.0.0-next.8@sveltejs/adapter-cloudflare:7.2.9