SvelteKit Hooks. Everything You Need To Know
Tags: svelte, sveltekit
Published: 2022-06-07 21:13:15



---
title: SvelteKit Hooks. Everything You Need To Know
description: A guide which gives you an introduction to SvelteKit hooks and how you can use it effectively in your application
cover_image: https://ik.imagekit.io/kudadam/blog/understanding-sveltekit-hooks/hero
excerpt: SvelteKit has something called hooks. A file which exports a set of functions which run on every request to the server.
tags: 
  - svelte
  - sveltekit
published: true
canonical: https://kudadam.com/blog/understanding-sveltekit-hooks
---

<p class="intro">
    SvelteKit has something called hooks. A file which exports a set of functions which run on every request to the server. It's really useful!
</p>

## Introduction

A SvelteKit hook is a file which exports four functions which you can use to modify data from your server. It is not compulsory for your app to contain a hook file but one is implemented by default if you don't create one. It exports four optional functions `handle`, `handleError`, `getSession` and `externalFetch`. With hooks, you can extend SvelteKit to suit your needs:wink:. 

### Use Cases of Hooks

A list of possible things which you can do with SvelteKit hooks.

* Redirecting a user
* Authenticating a user
* Minifying HTML, CSS and JavaScript response
* Getting the user session
* Setting cookies
* Fetching data from a database
* Handling errors
* Modifying fetch response
* Modifying HTML returned from the server

## Creating a Hook 

The default location for the hook file is `src/hooks.js` or if you prefer to use a folder, you can store your functions in an `index.js` file inside `src/hooks/` which will then make the path `src/hooks/index.js`.

Also, you can change the default path to the file inside your `svelte.config.js` file by editing the `config.kit.files.hooks ` value.

Listed below are the list of functions which are exported by hooks in SvelteKit.

## handle

The handle hook is a function which runs on every request to the server and also during prerendering. It allows us to access the request and modify the response. Inside the handle function, we can add custom data to the `request.locals` which will then be accessible to all the endpoints.

To simply put, the handle function acts like a middle-man who sits between the client and the server and intercepts the request before taking it back to the client. This allows us to perform a variety of actions to the response before sending it back. For example, we can decide to minify the HTML response before sending it back to the server or redirect a user who is not logged-in to the login page.

```javascript
export const handle = async ( { event, resolve })=> { return await resolve(event)}
```

The snippet above shows the bare minimum of how the `handle` hook works. It receives an `event` object which contains the request and an asynchronous `resolve` function which generates the response by taking in the event as parameter. Also included in the event object is the `clientAddress` (a getter function which returns the user's I.P address), `locals`(An object which allows you to pass custom data to your endpoints), `params` (an object which contains the value of the dynamic path), `platform` (a variable which contains the system's platform. It is usually set by the adapter), `routeId` and `url`. 

To add custom data to the request, just populate the `event.locals` with your data before returning the response. You can also minify your HTML generated by SvelteKit using hooks since it doesn't do that by default. I have [written a guide on how to do it](/blog/sveltekit-minify-rendered-html).

The `resolve` function also supports a second optional parameter that also gives us more control over the response.

1. ssr

   This allows us to disable server-side rendering. By default, it is set to `true`. If set to false. It renders an empty shell page.

   ```javascript
   /** @type {import('@sveltejs/kit').Handle} */
   
   export const handle = async ( { event, resolve })=>{
       const response = await resolve(event,{
           ssr: false
       });
       return response;
   }
   ```

2. transformPage

   This function allows you to apply custom transforms to the HTML document.

   ```javascript
   /** @type {import('@sveltejs/kit').Handle} */
   
   export const handle = async ( { event, resolve })=>{
       const response = await resolve(event,{
           transformPage: ({ html })=>{
               return html.replace("a","b")
           }
       });
       return response;
   }
   ```

   

### Multiple handle functions

SvelteKit allows you to chain multiple `handle` functions with the use of the `sequence` helper function. What the function does is that, it takes an array of functions and iterates through them and apply the handle function to each of them.

 Let's look at an example.

```javascript
import { sequence } from "@sveltejs/kit/hooks";

const first = async ( { event, resolve })=>{
    console.log("First handle start");
    const result = await resolve(event);
    console.log("First handle stop")
    return result;
}

const second = async ( { event, resolve })=>{
    console.log("Second handle start");
    const result = await resolve(event);
    console.log("Second handle stop");
    return result;
}


export const handle = sequence(first, second)
```

The resulting response will be:

```
First handle start
Second handle start
Second handle stop 
First handle stop  
```

As you can see from the resulting output, the `first` function will be called first followed by the `second` function but the `second` function will finish before the `first` function. Well, I still don't know the reason why it happens this way🤷‍♂️.

#### Fixing Common Errors Whiles Using The Sequence Helper

1. Cannot find package "@sveltejs/kit" on production build

   This problem is mostly found for those who use `adapter-node` whiles using the `sequence` helper function. The reason for this error is that, `adapter-node` doesn't bundle `@sveltejs/kit` with the build output so it doesn't find the `sequence` function when running the application in production.

   __Solution__

   1. Create a file called `sequence.js` and paste the sequence function code inside.

      You can get the source code from `node_modules/@sveltejs/kit/dist/hooks.js`.
	
   2. Then you import the sequence function from the file you just created.

      example below
   
      ```javascript
      import { sequence } from "./sequence.js";
      ```
   
      
   
   

## handleError

This is the hook responsible for handling errors in your application. Whenever an error is thrown when rendering your app, this function will be called with the `error` and the corresponding `event` that caused it. This function actually doesn't do much apart from reporting the errors in your application. It is mostly useful during production where you might want to get notified of every error that happens in your application. For example, you might want to write in a code that sends you an email each time your app receives an error.

During development, a frame will be displayed on your screen highlighting the cause of the error.

<aside class="note note__warning">
    The handleError function will not be called when pages and endpoints explicitly respond with 4xx and 5xx status codes
</aside>



## getSession

Since HTTP is a stateless protocol, it means the client and server forget about each other at the end of every request. In order to keep track of user's state, we use sessions to store data about the user. The data is stored in the server's memory.

The `getSession` hook allows you to access the `session` object. The function takes an event object and returns a session object. This function is run whenever SvelteKit server-renders a page. If it's unimplemented, the session is an empty object `{}`.

Apart from accessing the session object, you can also set the session inside this hook. Let's look at an example.

```javascript
export const getSession = (event)=>{
    return event.locals.user = {
        name: "John Doe",
        age: "20",
        id: 112244233434343
    }
}
```

In the example above, we set the session object with some values. In order to access the session in our page, we just need to retrieve it inside our load function.

```svelte
<script context="module">
	export const load = async ({ session })=>{
		return {
			props: {
			session
			}
		}
	}
</script>
```

Also, the data inside our session object will be accessible by endpoint if they access `event.request.locals`.

## externalFetch

This hook simply allows you to modify a fetch request that happens inside a `load` function that runs on the server. Any fetch to any external resource than runs on the server is handled by this function. Actually, it doesn't do much, the only important use case I found for it was making it hit API's directly instead of passing through proxies. This doesn't do much but it helps increase the speed of your fetch requests. Also, it allows you to modify the headers of your fetch request.



## Conclusion

This is a much detailed explanation of hooks in SvelteKit. If any information is missing out, please do write it in the comment section.