SvelteKit Internals: the handle hook
Justin Ahinon
Last updated on
Heads up!
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.server.ts
and src/hooks.client.ts
files (or their JS
equivalents).
The handle
hook
The 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 src/hooks.server.ts
.
The default behavior (if you don’t define a handle
hook) looks like this:
code loading...
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 handle
hook.
Protecting routes
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:
code loading...
Here you can see that we are also making use of the cookies
property, that’s also one of the available properties of the event
object.
Since the handle hook will run on every single request, we are sure that our route is properly protected.
Customizing responses
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:
code loading...
Using locals
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 load
functions.
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.
code loading...
Now, we can access the userId
in the load
function of the /admin
route:
code loading...
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.
code loading...
Wrapping up
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.