SvelteKit version: 1.0.0
Welcome back to the “SvelteKit Internals” series! In this second post, we will be exploring the handle hook in SvelteKit. If you missed the first post, you can find it here. Let's dive into the exciting details of the handle hook and see what it can do!
But first, what are hooks?
Hooks are a very interesting concept in SvelteKit. They are app-wide function that give you access to things like requests, responses, cookies, locals, etc…, allowing to do things like authentication, protecting routes, customizing responses, transforming resources, etc…
SvelteKit provides two categories of hooks: server hooks and client hooks.
Per convention, hooks are defined in the
src/hooks.client.ts files (or their
handle hook is likely the one you will be using the most in your SvelteKit applications. At its core, the handle hook acts as an interceptor for all the requests that are made to your application. Per default, it just resolves the request to a response, and returns it to make it available to other parts of the application (like
load functions, forms actions, etc…).
It is a server hook, so it should be defined in
The default behavior (if you don’t define a
handle hook) looks like this:
But that’s where the fun begins. Since you have access to the request and the response, you can do whatever you want with them. You can alter both of them, or even return a completely different response.
Things like authentication, authorization, rate limiting, etc… can be done in the
handle hook with a lot of granularity and flexibility.
Let’s say a few things that we can do with the
event object that is received by the
handle hook contains a lot of interesting information. A basic
console.log() of that object gives the following output:
add the two images
As you can see, the
event contains an
url property with the path of the current request. That means we could do something like this:
Here you can see that we are also making use of the
cookies property, that’s also one of the available properties of the
Since the handle hook will run on every single request, we are sure that our route is properly protected.
We can go a bit further by customizing the resolved response for the request. We can either alter the
resolve(event) response, or return a completely different response.
Let’s say we want to add a custom header to all the responses of our application. We could do something like this:
locals is a server-side only object that can be accessed in some hooks functions like
handle . It is not really within the scope for this post, but they can be useful in the handle function.
locals is an object that is built when a request come to the
handle function, and is passed with the request event to other server-side functions like
locals can come handy to store some data that need to be checked/validated on every request, like a user session, or a user profile data.
In our above example for protecting routes, let’s assume the authentication token is actually a JWT, and it contains the user ID. We could use the
locals object to store the user profile data, and make it available to other parts of the application.
Now, we can access the
userId in the
load function of the
We will then rely on
PageData to access the
userId in the component. See the load function post for more details about loading data and using them in components.
handle hook in sequence
In some situations, you might want to run multiple
handle hooks in sequence. SvelteKit provides a sequence module that allows you to do that. You basically define your handle hooks, and then use the
sequence function to run them in sequence.
In conclusion, the handle hook is an essential part of SvelteKit that allows you to add custom logic and tailor the way requests are handled. Whether it's for authentication, route protection, or customizing responses, the handle hook has you covered. To learn more about this powerful tool, be sure to check out the SvelteKit documentation.