Learn SvelteKit Hooks Through 6 Examples

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey friends today I'm going to show you something cool and that is water cell kit Hooks and how to use them for example so what are even hooks hooks can mean different things depending where you come from but in the case of soil kit you can think of hooks as middleware but they're more special because hooks can attach themselves to some other events and Trigger Behavior based on that so if you look at this example I made here here is the client and the server and usually you just send a request to the server and get a response but in case of middleware or hooks we can basically hook into the request right we can change the request which is going to change the response and you can do a lot of things we can use this for authentication modifying the response we can use it for error and performance logging and even creating automatic routes circuit uses a special hooks file that can be run on the client or server and it provides you with some server hooks like handle handle Fetch and some shared hooks like handle error but instead of boring you with Theory and exploring every API of hooks I'm going to show you examples as part your imagination because you really might not use hooks ever you're definitely going to encounter them if you use something like authentication but even in that case the library you're using is just going to give you the hook you're just going to include in the hooks file so let's really understand water Hooks and how to use them alright so I'm inside a regular silky project and I'm running a development server if you want to follow along you can scaffold your own project or you can just open stack Blitz and get up and running quickly so let's write your first hook and the most used and Powerful hook you're going to use is the handle hook which runs each time the swell kit server receives a request and it determines the response so inside of our project let's go to source and in your Source folder you need to create the hooks file so I can say new file and then I can say hooks let's create a server hook so we're going to say hooks.serverts let's close the sidebar and now we need to create a handle function that we're also going to export so I'm going to say export const handle and the type for handle is handle which should be Auto imported from circuit and then you can also say async let's give it a function body like this and that's it so let's say that you didn't add this hooks file what is the default behavior and basically the handle function takes an input object so this is going to be an input like this and this has some interesting things so if we look at it we can say input it has an event and resolve function so we can structure this in the function here you can just do it like this and this is how you're going to see it in most examples we can get an event resolve and what is the default behavior in a small kid application so basically it Returns the event which is the result so this is the function resolve and we're just going to say event and if we save this you don't have to reset your development server or anything like that it should just work so if we see this is just the default Behavior because otherwise if you didn't include this your editor will complain and now you get an SD error so let's get this back how it was you can just refresh and everything should work fine alright so let's change the default behavior and let's say that for every page I want to instead return a banana so instead of the default Behavior I can just remove this and I can say return and what we're going to return we're just going to return the response right which is the web standard as we already run so if we go to response mdn and we can go here and you can see the response interface of the fetch API Etc and these are just web standards right so this isn't something that swelkid invented and Etc and this is the beautiful thing about this so you can just say return new response and of course we can say it like this and we're just going to get a text back which is banana but let's do something more fun so we can add an emoji let's go banana let's save this and now if you refresh this let's also go to the network tab so you can see what's going on I'm going to refresh everything and we're just going to see that we get back our response banana preview banana right and here in the headers we can see this is just plain text but also notice something interesting what would be the default behavior when you go to a route that doesn't exist it will return a 404 right or not found but basically here we're overriding this and we're just returning a banana for everything so if we for example go to a route that doesn't exist like banana we're just going to get the banana back nope we get back the banana right so this is really interesting so let's say that you want to be more precise and how would we do this so basically we can just look at the path name and then if it starts with some route then we can just change that route and return the default Behavior so how can we do this here we can just go here and we can just let me just make space we can say if now we can from the event get URL which is really interesting so remember we previously install Kit see in this event object which has everything like cookies Fetch and Etc and you always come back to this object so this was really something that we dove into in the earlier parts so we can just take the URL we can get the path name so we can say hey does this start with some URL we can say banana and now in that case we just want to return a banana right otherwise we're just going to return the default so we can say return resolve event and now if you refresh this everything looks the same as before right but now when you go to our specific route banana they're going to get back the banana and this really might not seem like a lot but you just created a route through code which can be useful if you're making some library and don't want to make the user create a new route let's look at an example how hooks are used for authentication in circuit and usually the authentication flow is that you have some route like slash login or whatever the user fills in the form then you authenticate them and set the cookie so now you can get the cookie here from the event so for example you can have something like this session event cookies get you can get this session and now you can ping your database so you can say await get user you can pass the session but this really is just an example and this really isn't important I just want to focus on something way cooler which is for example now that you make a request inside your endpoint like for example slash admin and you want this user information so how can we get this data inside of our endpoints and for this you can populate the event.locosobject which is going to pass extra data to a request so you can do it like this you can say event not the way it counts we can just say event dot locals and you can name this whatever you want past whatever information or data you want but in this case I just want the user so I can name it test and now if this user is authenticated we can just populate this information for our entire application so let me show you how this is really awesome all right so in the sidebar I'm going to go through routes I was going to create a new file and let's create a user out and this is going to be a standalone endpoint so you can say server TS and because I'm using the circle extension we have some Snippets so I'm going to say kit endpoint and I'm just going to hover over the slide ball we can see add import from types and it's just going to import it for us and here you can see here is something interesting right again so here's this event object but if we just structure it we're going to see it has everything including locals so as you can see it contains custom data that was added to the request from the handle hook and now we can do this and I'm just curious is going to work if you just say locals so remember on the locals we have user so you can just do it like this and now we can save this actually let me just rename this locals and now if we go to slash user we can just get back the user or you can log it out or whatever else you want all right and this is cool but let me show you actually what you do most of the time when you do authentication in circuit so if I go back here I'm just going to close this I'm just going to create a plus layout dot server TS file because remember in a previous part we learned the data sent from a layout load function gets merged with data in child routes and this also becomes available in the page.data store so how does this really work and we can really ignore this so it's not confusing we can just delete this done so now inside the route you can just say plus layout server TS and then we can just say kit load like this and level function is going to be layout server load layout server load so this is going to actually what is going on let me just a little layout server load okay this is going to import it for us it is really awesome and now again here this is the same event object right so let me adjust the structure this locals and now what we can do here is we can return this data for all the child routes and this is how this works this is why when you try to use any off library or Etc they're going to make you do this they're going to make you get the locals from the layout server TS file and now you can say return user so we can say locals user and now you save this and this becomes available in your child routes through the data prop and also becomes available on the page.data store so let's see how something like this is really useful so when I go to the sidebar I'm just going to go to the plus page salt and I'm going to create a script this is a snippet I have and now we can say import we're going to import the page store from app stores and now inside of here we're going to get access to the information inside so we can say if page data user you can just say welcome page data user and since we have the user here is going to say hey welcome test and how awesome is this and this is basically because inside of our layout whatever your return here gets merged in the data object in your child routes but this also becomes available in the page.data store in circuit and because this runs on every request we can authenticate the user so we make sure nothing is wrong and this is going to get updated and this is going to get updated in your file so basically that's really the most simplest authentication flow in circuit let's look at how we can use hooks to transfer HTML and why would you want to transfer HTML one real world example I can immediately think of is internationalization so for example in your app you have different languages and you can change between them right but that's really not enough because if I press Ctrl P app.html so this is the default template in socket you also need to somehow replace this in your HTML markup so the language attribute which really isn't great to always leave it on English right so in this case you're going to see this if you use an internationalization Library so you don't really have to worry about it you have to do this yourself but let's do something cheeky here so we can just say percent and then let's just give it the placeholder right so this is something that we can Target ourselves and now we're going to save this and now we can go back to the hook and we can do something really special here so I'm going to remove this line so inside your hook you can get the Locale from your cookie or whatever so this is going to be something like Locale and you're going to be like event cookies get local or however you set it up again you don't really have to worry about this if you use an internationalization Library they're just going to give you the instructions but let's say for example that I want to use Croatian and now since I picked that language again remember now we can also pass it for our entire app so you can say event locals local yeah this is a mouthful try saying that a couple of times now we can say Locale right and this is really warning us because we also need to specify the type inside app.dts if you're using typescript but this really isn't important so I'm just going to ignore it and let me just put it here and now here is the fun part so when we return resolve event same as before but now we can pass some extra options here so you can pass it an object but what we want to use is the transform page chunk which is a really funny name if you ask me so you can just do this and this is basically just a function which is going to return something inside of here we have access to a couple of things like Don and HTML but basically this is going to give us the HTML of the request as a string so you really have to be careful in this case that you don't mess up the HTML because it might not be properly formatted but in this case what we can do is a simple replace so you can say HTML replace and now remember we have our percent length which we're going to Target and we're going to replace it with Locale that we go through the cookie or whatever and now you can see already it kicked in it really thinks we're using creation right so now when I open the developer tools let me just zoom in and if you go to the elements here you can see the language is set to creation and how awesome is this alright friends so let's look how we can use hooks to measure page load speed so hooks are really useful for something like measuring performance and error logging which you're going to look another example but for now I have this problematic page which you probably wouldn't know about in development it takes 2 seconds to load right so it would be really useful if we can log out a console log message only during development so here is this problematic page I just have a sleep function it takes two seconds now let's see how we can measure this using hooks so the first thing I want to know what page is slow right so let's just remove this and I'm going to say const route you can get a route using event URL and now we can start the performance measuring which is really simple so you can just say let start and we can use this useful function we can say performance now and now we can do whatever so we can say response so we're going to measure how long it takes for the response and we're going to resolve it right here and now we can say let end and we can say performance now again and now this is going to give us back our performance but to have the response time we can just say let response time so we're going to take the end and we're going to say minus start or we're going to subtract the start from the end alright cool and that's it basically so we can just say something like if response time is bigger than 2 000 milliseconds or two seconds right we can just say console log and now we can give it back text let's say turtle because emojis are fun and now we can say route took and now we can say response time because it is response time and we can say milliseconds and I'm also going to use to fix so it's not the large number it's going to round it to two decimals and this is really awesome so let's just copy this over is going to do it like this and now we can say if response time is below one second we're going to use a rocket and that's basically it and also since we already have this response right here right we just have to say return response and before I save let me just open our terminal and here we have it here now this should lock Turtle if I save this so let's see this is going to take two seconds awesome and now we get back our turtle and now it says the route and how long it took so if I go back here and if I just remove this you just give us back a rocket and how awesome is this as you can see it only took 24 milliseconds let's look at how you can use hooks for error handling in this case I'm throwing this error and as you can see because this is an unexpected error in circuit swelkit is going to strip this message and it's going to strip the stack Trace so we're only going to get this internal error message you might have some Gremlins in your code and want to send error reporting to a service like Sentry or log rocket and this is a perfect use case for the handle error hook which is a shared function meaning is the only hook that works inside hooks dot server TS and hooks or client yes and the handle error function is going to run if an unexpected error is from during loading or rendering so this see how that works here in our hook we have the default handle hook we can just delete everything and we're going to export the handle error hook so we can say export cones handle error we can use handle server error this is just going to import it and now we can say async like this and now we can just structure the error and the event not suvent which is really interesting I went like this and now you can do whatever you want basically this is it so you can say console log error and now if we open the terminal is going to say error but we can actually log out the actual error we can say error let's save it you can see here is the error so it doesn't hide the stack trace and Etc but if you want you can also change what is returned so you can say return and we can specify whatever you want message ID whatever you can say yikes exclamation mark let's give it a nice emoji and now instead of internal error you're going to get back yikes and this also becomes a part of your page data store so you get access to this inside your error page so you can customize this even further let's see how you can use hooks to modify a fetch response for example let's say they don't want to use HTTP or https for every request so we can use the handle fetch hook which is a hook to modify a fetch request inside a load or action function which runs on the server so here I can just remove all of this code I can say export const handle fetch which has the handle fetch type and now from here we can the structure request and fetch let's give it a function body and now we can just listen to the URL so you can say request URL if it starts with HTTP then let's change the request so we can first replace the URL so you can say request URL replace and now let's replace HTTP with https and now we can reassign the request so we can say request again just using web standards we can pass in the URL and the original request object and I can even console log out request URL and before I saved it we also need to resolve it so we have to return fetch request and let me just open the terminal so here we use HTTP and now we change the request and this should log out https so let me just save everything and you should see everything works as expected and how awesome is this let's look at an awesome use case for hooks which is parsing form data you already know that working with forms is a pain even if you're using swellkit and it makes everything easy for you how this works is basically you just submit what you have right and then you have some form actions here but now you need to get the form data you need to validate or Loop over each field before you can pass it to something like salt and this is very tedious so what if you could just make a hook that parses that form data for you and just gives you the parsed form data and you can let's look at how we can achieve that so first I'm going to go here to Hooks and already have a handle hook here but I'm also going to use another Library which is parse form data and this is going to take care of the parsing for us we don't really have to even think about it we can import it from parse nested form data so let's see how we can make this work so I'm just going to remove this so we know what's going on and now we can just listen to the request and if the method is pulsed right which is from our form then we know it's a form request and we can parse the form data so we can say if event request method is equal post and now we can get the form data from the request so we can say const form data await event from the request form data and now we can parse the form data into a Json object using this package imported so I can say const data parse form data and I can pass form data and also let's not forget to include async here and before we're not done yet so how do we make it available inside our actions here so remember we already learned about locals and we can do the same trick here to pass the form data to the request so here I can go and just say event locals form data and we can just pass it the same data how beautiful is this and now don't forget we need to resolve the event like this let me just save it and now here let me just log out locals so now we don't have to parse the form data and how awesome is this so let me just save this I'm going to open the terminal let's say for the username test password one two three four and let's say remember me and now they should parse the form data for us and how beautiful is this so we get the form data object username test password and this is really a weird thing when you submit forms it since everything is a string it's not a Boolean solo the value is on going to be for a checkbox and we can even let's say phone data here let me just do it again test one two three four remember me and now you can pass this to zodo Rotary let me show you another beautiful thing about this Library past form data for example you can do different things with it and if you want to pass some values to null or Boolean for example you can go to the value in this case remember and now for this Library you can use Ampersand and now look what's going to happen when I say for example test one two three four remember me it's going to convert it to a Boolean so you can see username test password to three four remember true and how awesome is this and also if you're using typescript right here inside your app.tts you're going to have an error here because you haven't typed locals but let's go to app DTS and now here where your interface is previously we had user I can just remove this but now you can specify this typeform data which is a record string of type and no and now you won't get an error anymore alright friends in the last example let's look at how we can use multiple hooks together so you're going to see this when using a library that gives you a hook is going to have a different name of course you don't have to use event for the name right but what if you have multiple hooks then so for example here you have an off hook which is going to deal with authentication here I have an internationalization hook that's going to deal with the internationalization and basically to use multiple hooks together you can use the sequence helper function from toolkit and everything is going to work great so let's see how we can do that and we can just say export const handle we can import sequence from circuit and now we can pass it all the hooks you have and that's simple as that okay so now if you open the terminal before I save it so you can see here it is imported from circuit and now we included all of our hooks so you can save your hooks for later and reuse them and now we can save it we can see our off hook run and our internalization hook Ram alright so that's it so okay hooks are very powerful and I hope you now understand how they work and when to reach for them if you have to if you found this useful don't forget to like And subscribe and if you want to support me you can find my patreon in the description thank you for watching and catch you in the next one peace [Music] now foreign
Info
Channel: Joy of Code
Views: 13,495
Rating: undefined out of 5
Keywords: svelte, sveltekit, hooks
Id: Kzrz7GZ9pIg
Channel Id: undefined
Length: 23min 54sec (1434 seconds)
Published: Fri Feb 24 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.