SvelteKit Internals: the handle hook

Justin Ahinon
Last updated on
Table of Contents

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:
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:
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:
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.
Now, we can access the
userId
in the
load
function of the
/admin
route:
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.
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.