sveltejs/kit · error · Error
Cannot access event.url.hash. Consider using `page.url.hash`
Error message
Cannot access event.url.hash. Consider using `page.url.hash` inside a component instead
What it means
Server-side `event.url` in SvelteKit is a URL whose `hash` property is redefined to throw, because the URL fragment is never sent to the server — the server simply cannot know it. Accessing `event.url.hash` in server code (load functions, hooks, endpoints) therefore throws immediately, with a message pointing to `page.url.hash` in components where the client-side value is available.
Source
Thrown at packages/kit/src/utils/url.js:187
}
if ((DEV || !BROWSER) && !allow_hash) {
disable_hash(tracked);
}
return tracked;
}
/**
* Disallow access to `url.hash` on the server and in `load`
* @param {URL} url
*/
function disable_hash(url) {
allow_nodejs_console_log(url);
Object.defineProperty(url, 'hash', {
get() {
throw new Error(
'Cannot access event.url.hash. Consider using `page.url.hash` inside a component instead'
);
}
});
}
/**
* Disallow access to `url.search` and `url.searchParams` during prerendering
* @param {URL} url
*/
export function disable_search(url) {
allow_nodejs_console_log(url);
for (const property of ['search', 'searchParams']) {
Object.defineProperty(url, property, {
get() {
throw new Error(`Cannot access url.${property} on a page with prerendering enabled`);
}View on GitHub (pinned to 03f1687fe6)
Solutions
- Move the hash-dependent logic into a component/universal load using `page.url.hash` from `$app/stores`/`$app/state`
- Drop the hash on the server — it is always absent from requests, so use `event.url.pathname + event.url.search`
- Guard with `browser` (from `$app/environment`) when code runs in both environments
Example fix
// before (+page.server.ts)
const full = event.url.href; // or event.url.hash
// after (+page.svelte.ts / component)
import { page } from '$app/state';
const hash = page.url.hash; // client only; server never sees the fragment Defensive patterns
Strategy: try-catch
Validate before calling
import { browser } from '$app/environment';
if (!browser) {
// never read .hash on server-side event.url
console.assert(!('hashAccess' in plan), 'logic must not rely on url.hash server-side');
} Type guard
function canReadHash(url) {
try {
void url.hash;
return true;
} catch {
return false;
}
} Try / catch
let hash = '';
try {
hash = event.url.hash;
} catch {
// fragment never reaches the server; fall back to pathname + search
const url = event.url.pathname + event.url.search;
} Prevention
- Never read event.url.hash in server modules — the fragment is not sent in HTTP requests
- Use page.url.hash in components/universal code for the client-side fragment
- For shared helpers, branch on `browser` from $app/environment before touching .hash
- When logging URLs server-side, build from pathname + search, not href with hash access
When it happens
Trigger: Reading `event.url.hash` (directly or via destructuring/logging) inside `+page.server.ts`/`+server.ts` load functions, server hooks (`handle`, `locals`), or `getRequestEvent` context on the server.
Common situations: Logging the full URL server-side (`console.log(event.url.href)` still works, but explicit `.hash` access throws); porting client code that reads `page.url.hash` into a server module; building canonical URLs and including hash defensively; generic URL-manipulation helpers shared between server and client.
Related errors
- Cannot access cloudflare:workers in a prerenderable route
- ${keypath} option must be an absolute path, if specified. Se
- ${keypath} option must not end with '/'. See https://svelte.
- ${keypath} must be a valid origin (e.g. 'https://my-site.com
- ${keypath} must be a valid origin — only 'http' and 'https'
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/f7409b32425ccaf8.
Report an issue: GitHub.