SvelteKit Hooks and Server Runtime
Server runtime hooks in SvelteKit — hooks.server.js and hooks.client.js, the handle function, handleFetch, handleError, locals, and server-side middleware patterns.
Hooks are functions that run at the application lifecycle level in SvelteKit, providing middleware-like functionality.
hooks.server.js
Runs on the server for every request. The primary hooks are:
handle
Wraps every request. Receives the event object and a resolve function. Can modify the request, add to locals, or short-circuit the response.
// hooks.server.js
export async function handle({ event, resolve }) {
event.locals.user = await getUserFromSession(event.cookies)
return await resolve(event)
} handleFetch
Intercepts all fetch calls made in load functions and actions. Useful for adding auth headers or modifying request URLs.
export async function handleFetch({ event, request, fetch }) {
request.headers.set('Authorization', `Bearer ${event.locals.token}`)
return fetch(request)
} handleError
Catches unhandled errors during rendering or data loading. Log errors and return a sanitized error object.
export function handleError({ error, event }) {
console.error('Server error:', error)
return { message: 'An unexpected error occurred' }
} hooks.client.js
Runs on the client for navigation events:
// hooks.client.js
export function handleError({ error, event }) {
console.error('Client error:', error)
} The locals Object
event.locals is populated in handle and available in all subsequent load functions and actions. It’s the standard place for authentication data, database connections, and request-scoped state.
// app.d.ts (typing locals)
declare global {
namespace App {
interface Locals {
user: { id: string; name: string } | null
}
}
} Lifecycle Hooks
Beyond the server hooks, Svelte 5 provides component lifecycle functions: onMount, onDestroy, beforeUpdate, afterUpdate, and tick. These run in both server and client components.
Best Practices
- Load user/session data in
handlerather than in every load function - Use
handleFetchfor consistent fetch configuration - Keep hooks thin — delegate to separate modules
- Type
App.Localsinapp.d.tsfor full type safety - Avoid heavy computation in hooks (it runs on every request)
See Also
- SvelteKit Authentication — common auth patterns that use hooks
- SvelteKit Data Loading — where locals are consumed
- SvelteKit Error Handling — error handling across hooks and routes
- SvelteKit TypeScript — typing App.Locals and other app boundaries
