Okupter

SvelteKit Internals: the handle hook

Justin's profile pic

Justin Ahinon

Last updated on

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:

TYPESCRIPT

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:

TYPESCRIPT

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:

TYPESCRIPT

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.

TYPESCRIPT

Now, we can access the userId in the load function of the /admin route:

TYPESCRIPT

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.

TYPESCRIPT

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.

Join Okupter's Mailing List

Join Okupter's mailing list to get regular updates on web development, accessibility, performance, and more.