Learn How To Build Modern Web Apps With SvelteKit

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey friends I hope you're excited about learning swellkit if you don't know swelkit is a Swiss army knife of web Frameworks for building resilient apps that run anywhere where JavaScript runs this is a compilation of the silky series I made and we're going to learn a lot more than swelkid like learning about web fundamentals which is transferable knowledge you can use anywhere so in the first part we're going to learn what silk it is which is going to be really comprehensive introduction so what is cell kit what problems does swelki solve and Etc so I really want to give you that mental model to understand what you're using then you're going to learn how to set up spell hit from scratch to understand how it works I want to give you confidence to understand how cell kit works so you're going to have more confidence when you're working on your app then you're going to learn everything about selfie routing which is Pages layout necess route which is really powerful in cell kit they're going to learn about circuit API routes and server-side rendering pages so how do you get data to your pages data fetching and Etc in the next part you're going to learn everything you should know about working in forms in some okay because you can do anything without forms and salt makes it super easy to work with forms including Progressive enhancement and to be honest just by watching these five parts is enough to get started so you can start making a to-do app because it's really great to use everything you learned so far because it involves creating reading updating and deleting something but then if you want to learn about more advanced things you can learn about Advanced layouts in cell kit you can learn then about swell kit hooks which is swell kid middleware and then of course if you want to deploy your application you can learn how to do so at no cost using versel Super Bass Prisma and postgresql the only prerequisite for this course is that you know some basic JavaScript and if you want to learn swelt I have an entire series on learnings field you can watch first and this is going to teach you sweld for JavaScript where I'm going to show you a JavaScript example and then I'm going to show you the equivalent in swelt so if you want to support me you can like And subscribe or you can become a patron if you want certain lowest one dollar amount and of course if you need help or have questions join in the Discord and you can get help that way and I also want to say that the best way to learn is to get your hands dirty so don't just passively consume content challenge your mental model try it out that's the best way to learn alright but enough talking let's get started swelkid is the Swiss army knife of JavaScript Frameworks soak it is basically a meta framework built on top of swell for building Rich web apps but it's easier to honestly think of it as a backend framework that uses wealth as the component framework first let's have a look at the swell kit landing page so it's fast fun and flexible silky is powered by wheat and speed is baked into every crevice it's fast setup fast development fast builds because it has live reload so if we can see here is wheat swelkid uses veed for the server and server side rendering hot module replacement so when you make a change to your CSS or JavaScript is going to update immediately in your browser silkit is fun no more wasted days figuring out bundler configurations routing server-side rendering CSP typescript deployment settings and all other boring stuff code with joy selkit is also flexible most JavaScript Frameworks force you into something like static size generation or being a spa or server side rendering but you can do everything with circuit you can have a single page application a multi-page application server-side rendering static size generation in a single app and I'm going to show you more about it later and if you don't trust me the best quote is from Scott olinsky what swelt allows us to do is to write code how profound is that her Jokes Aside swelkit is built on top of swell if you don't know about swelt I have an entire Series where I teach you swell through JavaScript if you're interested in that and if you already didn't know swelt is a UI framework that uses a compiler to let you write breathtakingly concise components that do minimal work in the browser the best thing about swelt is that you can use the languages you already know HTML CSS and JavaScript it's a love letter to web development another amazing thing about swelkit is that you can deploy it anywhere you can pre-render your sites you can run it on a node server you can deploy to your cell netlify Dino if you want thanks to cell kit adapters swelkit is basically a machine that turns a request into a response so you're not tied to something like just node.js and you can deploy it anywhere if you're familiar with other JavaScript Frameworks swelkit is to swelt what next year is or remix is to react but philosophically swellkit is closer to remix where it encourages you to use the web platform and Progressive enhancement to build more resilient sites this might not mean anything to you right now but don't worry we're going to go through everything and I'm going to show you examples what makes swellkit great so don't worry if you're lost or you don't understand everything because you're going to dive deep into those things later swellkit blurs the line between the front end and the back end it makes the integration between them seamless since it has control over both which means you can start working on a project and not suffer from decision fatigue since it's opinionated in the right way you can use swellkit for example to create an API just like you can with Express which you can use inside your application but you can also expose it to the world and if you want to do that you need to set up course and all that fun stuff but let me just quickly show you what I mean so here I have a simple plus server TS file and this really isn't important right now but I just want to show you how simple it is to make an endpoint so for example here I want to fetch a list of posts from a database so you can pretend that I'm making here a database call and I'm going to return pulse is just an array of objects and then I'm going to use this Json helper from swelkit to return the post so I don't have to write my own response headers and Etc and if we look at the sidebar so let me just go here and I can reveal in Explorer view so you can see I created an API folder which is not convention you can name this wherever you want like banana Etc so I created API post and I created the server file and just like that I can go to localhost 5173 slash API the folder I created slash post and that's it now I can use this API inside my app or expose it to the world and that's how simple it is in cell kit this is cool and everything but where silky shines is when it comes to data fetching for your pages because of how seamless the integration is between the back end and the front end and it gives you type safety so you don't even need something like trpc and let me show you what I mean so here I have a swellkit project and I'm just going to fetch a post from the database again we're going to pretend that this is on post so here I have another interesting file plus page server TS and this is similar to our own endpoint before but this is a page endpoint so this is exclusively responsible for fetching some data from the file system or database for your page so you can see here we have this load function and that's really not important for now so you can again pretend that you're fetching something from the database you're going to get to post the slug the content so you can pretend this is some content manager system and it's simple as just returning the data from the load function and now in our page where I have here data we get type safety for free because swelky General is the types behind the scenes for us so if I hover over data we can see ah here is data here is the post Etc and now when you do whatever in your template or here you can see you get great Auto completion but don't worry if you're scared of typescript or don't know typescript you can use JS Dock with regular JavaScript so you can also get great types and let me show you an example of that if I go to the Circuit documentation for example I'm just going to zoom Mount so I can get the entire View and here you have this handy toggle so for example let's look at an example here so here it's importing this type whatever but you're like okay I don't use JavaScript I'm just going I don't use typescript that is I just use JavaScript so you can just toggle that and it's going to give you the JS doc version so you can just paste it over this is how you learn what the type is and you can go on your way but yeah I prefer typescript so let me just go back here and again now you get the data from the server how awesome is that and easy swellkit has a strong emphasis on convention over configuration silken Sparks Joy because it doesn't get in your way so you can start hacking at your idea and not spend hours configuring things I mentioned how cell kit is a veed plugin but that's an oversimplification and sounds like a weekend project considering the problem it solves so here is the big question why would you use swelkid what is wrong with soil there's nothing wrong with soil swelt is a separate project and you can Implement your own routing and Etc there's packages for that so you can do whatever you want and they're always going to be separate projects so if you're thinking that swelki somehow replaces well that's false it's just a recommended way to build swell tabs because of all of these things so what is the problem that sulkit solves well sulky does routing for you so you have file based routing it's all server-side rendering it solves data featuring as we've seen before the best part is zero config so it configures easily prettier typescript testing with playwright and v-test out of the box so basically when you scaffold a selfie project you get questions in the CLI and you can pick whatever you want from these options and it's going to be configured for you but of course zero configuration doesn't mean no configurations you can configure it however you want this is a more spooky sound you want what does code splitting mean well basically swellkit is smart enough that it knows the data for each page so it knows what to load in terms of CSS and JavaScript for every page so an awesome thing in cell kit is you can get pre-loading so when you hover over a link it's already going to start downloading data for the next page and those precious milliseconds are going to be a huge gain in terms of perceived performance socket also handles environment variables for you and this just goes beyond just being able to import environment variables because it's going to save you when you for example try to import some secret environment variables on the client is going to be like hey you can do that and that's going to be the end of the story so silky is going to try its best to set you up for success and also unlike other Frameworks circuit has configurable rendering you can have server side rendering static side generation and client-side rendering in the same application so for example your marketing Pages can be statically generated your app can use server-side rendering and you can even disable server-side rendering and disable client-side navigation if you want basically once your first page loads it uses server-side rendering because server-side rendering is faster and better for SEO so if that's something you need you can just enable it and you don't have to just make a single choice and also the best part of it it configures deployment for you so you don't have to think about that you don't have to think about optimize bundle sizes and Etc it just works swellkit is the best of both worlds it's server-side rendering with client-side navigation what does that mean so here an example where we fetched our post in a regular single page application this would just be some JavaScript shell and we really wouldn't have the HTML in our source which would be bad for SEO while the Google search engine can parse JavaScript it shouldn't be relied upon because it takes compute so you really can't rely on that for SEO so if I go for example here and say page Source we can see our HTML is right here so this is really great for SEO and we can see some interesting things here so what is this basically this is responsible for hydration but it also loads the client-side router and what does that really mean basically the first time you load the page in swellkit is going to server side render it so it's going to give you the data from the server and then after that it basically becomes a single page application so you retain that awesome user experience using a single page application this wasn't using client-side routing when we would navigate from link to link here our page here with refresher but that's not the case with 12K because the router kicks in so for example if I go to app you're going to see everything is going to stay smooth and there is no page reload and as I said most Frameworks make you decide between server-side rendering or pre-rendering everything but spell kit lets you choose what method you want on a per page basis I also have a handy diagram here to show you how a spa Works basically if you're used to that so basically when you're using a spa you make a round trip because first all your JavaScript has to load before you can even request data from the server so you have the server it takes a request index.html and this downloads some shell where you just uses JavaScript to populate content and change things on the page so then you have a get request for the API post and then you can get your post and show them on the page but with server side rendering and the benefit of this is that you do this all in one take so before you even show the page you can just say get API post and then you just get the data in the index HTML or whatever and then you might be asking about okay what if this takes some time to get the data and the answer is then you have a problem with your infrastructure or caching which is great because it's more easily soluble than just using a spa and relying on JavaScript so to repeat swellkit apps are server side render by default for Speed and SEO so search engine optimization but once the page is loaded the client-side router kicks in which makes your F feel like a spot to avoid reloading the page between page navigation so let me just quickly show you how awesome it is to be able to set what rendering mode you want on a per page basis or even for the entire site so here my project in the root layout I have this plus layout TS file and if you wanted you can pre-render the entire page so you can set here pre-render true and then you can change this for individual pages so this would overwrite it but I'm going to comment this out and I'm going to show you for example if I go to the about for example I want to pre-render this or whatever and here I have this about folder nothing special here is the file with some Styles and HTML so I can go here and then I can say pre-render is true so it's going to pre-render it and then I can even disable the client-side router so I get zero JavaScript and this isn't going to work in development so you need to build your page I'm going to say pnpm run build and I'm going to run preview this is going to take a second and let me just quickly show you how awesome this is for example here is a special generated swell kit folder so you can see here in the output pre-rendered you can go to Pages here and here is the about so this is just going to compute in advance the data you need for the page and as you can see there is no JavaScript here so for example I'm in the build so you can just go to 4173 and then let's just view source and you're going to see it's the same thing so there is really no JavaScript here which is really awesome if that's what you want so right now even the router from the cell kit isn't loaded so when we navigate to home our page is going to do a hard refresh because the client-side router hasn't kicked in yet so for example if you go from about now to home you can see how it does a hard refresh but for example now since we're on home if we go back to about it's still going to be pre-rendered everything but now it's going to use the client-side routing so you can see how awesome this is so here is another example where this might be useful so if I go to app here let me just go to the sidebar and we're going to close this and here is my app so here let me just uncomment so here we're fetching actually let me just open the development and run Dev and go back to that and of course the URL is different say 5173 so here you see internal error and why is that remember how I said that your components run on the server and client so for example if we continue using the client router I go to home back to app is going to work because this is just in the context of the browser but if I refresh the page so someone visits your page for example and this is going to run on the server and what do you do now there's a couple of things you can do but again we can just change the rendering mode so here in our app we can go to page DS and we can just disable server side rendering and how awesome is this and we did on a per page basis this is just amazing to me and completely mind-blowing since most JavaScript Frameworks force you into using server-side rendering or pre-rendering everything sulkit uses the web platform but what does that really mean one thing I love the most about swell for example links you don't have some weird wrapper for links because it's just regular HTML as you can see here in the navigation I didn't have to import some weird component or whatever else I just wrote regular HTML but what does it really mean to use the web platform let's have an example if we go to the login so let's see how simple it is working with forms in cell kit again if I go here to the example there is no real component I had to import Etc I'm just using the form and this is the beauty of cell kit because you're going to spend more time on mdn learning about the web platform than some weird abstraction that's only useful inside swelkit and circuit uses the web platform meaning you're not learning some framework specific abstraction but using web standards like the fetch API the request and response object headers form data cookies and Etc so you're not going to read the swell docs and some of these things you're going to read about and learn about the fetch API which is transferable knowledge you might have forgotten how forms work if you use traditional JavaScript Frameworks over the years right so here I have this interesting action which really isn't some weird swell key thing is just a URL right and this action points to something awesome this plus page 30 s which exports these actions and actions basically you can just Define a method you want to run when you run something from the form and here in this object you can get access to the request cookies that you can do whatever so question for example how do you get data from the form we're of course using the web platform we're using the form data so you can go to mdn you can see okay new form data and you just pass the form and you get the form data so here on this page I can for example say test one two three four and before I submit let me just open the terminal remember this is going to run on the server so here is where you can set all your cookies and silk it also exposes a nice API for the cookies so you don't have to import your package and Etc so here's how you can get the credentials we can just say data get because remember this is just the web API or how to get data from a form you can get the name password and then you're going to console log it out or do whatever you want so now when I say login you're going to see name test and password one two three four and that's how easy it is to work with forms in circuit swelkit apps are more resilient because they use Progressive enhancement your swellkit apps Works before JavaScript if you haven't noticed in this example we're not even using JavaScript remember how we typed in test one two three four and pay attention to the browser because this is going to reload the default form Behavior right you can use Progressive enhancement if swellkit if you want to progressively enhance the user experience and this is really simple so here you can enable the swelt action enhance and you can just go here you can say use enhance and basically when JavaScript is available on the page it's going to use it so instead of disabling the default form behavior and implementing what the browser does yourself swelkit really makes it simple to use the web platform and progressively enhance the user experience when JavaScript is available on the page so if you're curious this basically does the equivalent of if you weren't using this you would be doing something like on submit and then you will be like handle submit and then you would have to go here in your JavaScript function handle submit you would get the event and then you have to say prevent default and then you would have to fetch Etc but notice there is not a single fetch here because swelke does all of it for you let me just remove this and let me just show you that this is true it's going to remove this so we just had to use enhance let me just save it I'm going to open the terminal again and now when I go here I'm going to say test one two three four and notice how we're not going to get a refresh here we're going to say login and now we're using JavaScript and how great is this we talked about this briefly about swelkid runs where JavaScript runs silky by default uses the node.js adapter but it can run anywhere where JavaScript can run requiring zero configuration thanks to adapters you can even write your own adapter but one of the supported environments are cloudflare Pages netlify versus node.js or you can even pre-render your entire page using the static adapter and there's even Community adapters for things like Dino and Etc but also keep in mind if you're going to run circuit in an environment that is not node.js and you're trying to use node.js file system API for example that's not going to work so here we can see the documentation here the adapter so supported environments cloudfare Pages netlif3 or cell and this is really simple as that so for example if you want to deploy to our cell you just point it to your GitHub repository and that's it basically it's going to work you can create an old version and there's many other things you can do you can export your own custom server using websockets and Etc if you need that so here is the the adapter static so you have Community adapters if you go here there's Dino and other ones like bun I think so yeah basically this is very interesting swelkit makes the deployment story really easy let me also briefly mention that swellkit is also great for making component libraries so you can package and publish your packages on npm and circuit helps you create and publish packages if you're working on component libraries using swelt package so a component library is similar to a cell Kit app but the root is going to be inside source lip and when you run swell package is going to do everything for you and you can publish it directly to npm so you can see here is the packaging and if you're a library offer or retainer cell kit also makes this process really simple alright friends so I hope you're excited about swellkit and want to learn more and remember swelkit is made for everyone so it is an open source project governed by Rich Harris and a team of core contributors the development is funded by the open Collective anniversal but it's not governed by a corporation whose goals are ambitious and unclear the future of circuit is bright and I hope you give it a try but be warned in case you do you might not want to use anything else any side effects include a permanent green on your face I don't know about you but when I'm learning something I want at least a high level understanding of what makes it work understanding what makes swellkit work is going to give you more confidence using it as you get more familiar with it like getting to know a friend and there's a lot of people that are newer to development and don't even know about these files and they're going to be the same across most JavaScript projects I'm going to show you how to set up swellkit yourself without the CLI but don't worry we're going to use off the shelf Parts instead of doing swell kit from scratch after that I'm going to walk you through the soil kit CLI and explain every file so you at least understand the purpose of it and if you're one of those weird people that want to understand how silk it works under the hood well I'm that weird type of person that made learn how swelkit works that you can read or watch so you can go here you can get the popcorn or you can read it or watch it alright so let's get started I'm just going to create a new tab so you don't get distracted and I'm going to open a new terminal and to be honest with you it's been a while since I actually created a project from scratch because I'm so used to using some CLI but basically in the post I use npm but honestly if you want to save your hard drive please get set up pnpm because it's going to reuse packages for your project so it doesn't destroy your hard drive and I really love it so I'm going to use pnpm here but the commands almost map one to one with npm but it's up to you so I can say pnpm in it and basically it's going to create the Json file so let me just close the terminal and here in the sidebar here is a package Json and I just like to remove most of this junk we're going to add scripts ourselves basically we could have created this file by hand but basically that's how you do it save this so let me just open the terminal and we're going to need some packages so what is the minimum required amount of packages for soil kit and it's surprisingly a low amount so there's four packages we need to install I think so let's go we can say pnpmi we need to install them as a development dependencies so you can already see here is Veet then we need swelkit itself cell kit is just a vid plugin so that's why we need Veet and then we're also optionally going to install the adapter and swelt for the component framework so I'm just going to install it like this and you should populate our package.json give it a second and you can already see the blazingly fast speed of pnpm and this is just because I save this file but if I autoform it I'm just going to predify everything so let me just close the terminal so you don't get distracted and at the top I'm going to declare that we're going to use a type module and you might see this in circuit projects we're definitely going to see it because silk it uses native JavaScript or ecmascript modules and what it basically means if I go here so that's basically this syntax so you can say import package from package and in the past this wasn't supported by the browser so you needed a bundler to transpile this so it understands it using the old common JS or require syntax so if you're familiar maybe something like this require and then you do this and basically this is using the native JavaScript modules that's part of the spec and that's something that browsers understand okay I'm just going to close this and basically I'm just going to add a type here and I'm going to say module here you can see it offers us common jsr module another thing worth mentioning is if you're using native JavaScript modules and you want to use something that's common.js you can just suffix it with the dot CJs type in your project and it's going to work so that's great but we're going to need some scripts to run the development mode to be able to build a project in pre-read and basically scripts are just a way to run some script from your file system usually from the node modules folder so I can go here I can just say Scripts and then we're going to add one for development and then we can just say wheat Dev we can add one for building the project create build and then let's add one for preview so we can say wheat preview and let me just save and this is going to Auto format by the way if you want Auto formatting in your editor you can go to your vs code settings and enable format on save so if you're using prettier it's going to do everything for you basically or you can look it up how to do it for the editor you're using and basically that's it we just need to do a couple of more things so swellkit requires a Veet configure to root of the project in the previous part I talked about how cell kit is a Veet plugin and I'm going to show you that so let me just close this file I'm going to open the sidebar I'm going to create a new file which is going to be name wheat config.js let's just keep it simple I'm going to close the sidebar so let me just import the circuit plugin that's exposed from swell Js kit wheat so here we can also include some JS Dock types we can say type import and we can just say here user config so you just get Auto completion because you're not using typescript for this file so here's the magic sauce so we can just say const config now we specify wheat plugins and right with plugin we want to use socket of course and that's basically it this is the Beating Heart of swellkit and we just need to export the config export default config let's just save it and that's basically it you can also optionally include a swell config file so you can get pre-processing and adapter to Output your project and I'm going to explain what it means in a second so let's do that because we can so we can say sweld config.js and now I'm going to import the adapter reinstall so you can save from so JS adapter Auto and now we're going to import the preprocessor so you can say wheat pre-process and it already Auto completed this for me which is awesome so let me just include the JS Dock here say type import is going to come from swill.js kit and from here we just want the config and now we can also give it a config like we did for read so we can say cons config so we're going to declare a preprocessor so you already see how you get great Auto completion and then we're going to save it preprocess which we imported and Now options for cell kit we can say kit we can specify an adapter and we can just use the adapter and also don't forget to export your config export default config save it and that's it so let me explain what these things are a preprocessor transfers your dot swell file before passing it to the compiler in this case Veet pre-process handles typescript post CSS and scss or SAS as some of the language flavors which you can read more about in the swelki documentation so if you go here to Integrations it tells you the same thing I did right now for preprocessors as you can see here in David pre-process section V plugin soiled offers a wheat pre-process feature which utilizes Veet for pre-processing and you also have some other fun preprocessor you can use or whatever and basically this is a really fascinating thing you can for example make preprocessors that maybe turn your dotswelt files into slidex or whatever that's actually a fun little project I worked on previously and I might make a video on that in the future I talked about it previously but an adapter is used to adapt your cell Kit app to the deployment Target you can write your own adapter but as you supported adapters include Cloud Fair pages so you can go here you can host your cell Kit app no problem with your configuration netlify awesome host versus awesome host you can also do node.js you can use a static adapter if your entire app is a static site you can even use Community adapters to deploy to Target platforms like Dino for example but alright we're not done yet so let me just go to the new tab so it's not distracting I'm going to close this so now swelkit expects a HTML page template with placeholders that swellkit uses and replaces for your pages so inside of here I'm going to create a new file which is a Nifty trick so I'm going to say Source in vs code and then I'm going to say app HTML that's going to create a folder source with a file app.html inside let me just close the sidebar briefly and I'm going to commit a crime and write awful markup but thanks to browsers understanding being able to build proper HTML Pages this is going to work fine so you can just say it and now we can use swellkit dot head so I can close it like this and I'm also going to need a body so we're also going to say swellkit dot body and let me complete this I'm going to save this and this is almost it but we need to do one more thing and that's adding our route that's going to be the first page someone sees when they visit the site so I'm going to open the sidebar again inside of source I'm going to again do new file I'm going to create a folder routes and I'm going to create a special file plus page swelt so you can see here is the route folders and the file we created so I'm just going to use a H1 tag and I'm going to say hello I'm going to open the terminal now clear everything so now we can run development mode and everything should work so we can say peer PM run Dev and awesome our Port started on localhost 5173 and if you're curious why is it using this weird number and apparently the V developers are comedians because you might have noticed it but 5173 is lead speak for wheat or it can even spell outside so it's really hilarious in my opinion but yeah it basically that explains it and it's really interesting but okay enough talking let's just go to that Port so you can say localhost 5173 and everything should work and it does awesome but we also get some one error which is the favicon so you can also include a static folder here you can include the favicon but I'm not going to do that so let me just close the terminal and one thing worth talking about is also that swelkit creates a special thought swelt dash kit folder that has all your generated files as you work on your project so you can ignore or delete this folder because it's going to regenerate each time you run Dev or build and this is how for example the magic Source works for generating types for your pages which you can find in this folder and this is usually going to be the output of your project and you're going to see a types folder here you can see the type generated right here so basically that's it for sulky from scratch and in the next section I'm going to show you how to use the cell kit CLI where I'm going to explain every file and folder alright so I deleted everything so you can start fresh and here we're going to use the recommended way of scaffolding as well key project which is using the swellkit CR I so I'm going to open the terminal and if you're following these steps along and if you're new to this you're going to need node.js at least so you can run this type of commands you can also get pnpm or you can use npm if you prefer so how do we scaffold a swell project where it's very simple so I can just say pmpm create in my case and I can just say pnpm create swelt and this is going to start an installation wizard so it's going to ask you where should we create your project I just want to create it in the same folder so I'm just going to press dot or leave it blank I'm going to do and now it asks you what you want to do so you can get the demo app which has a lot of examples you can create a skeleton project that's empty barely has anything and then you can create a project if you're working on a library but I'm going to pick the skeleton project I'm going to pick typescript but if you want you can use JavaScript so I'm going to pick the texture syntax we really want eslint we really want prettier and also going to say yes to everything basically so I can explain it we want yes for playwright v test let's just say yes and then when this is all done you have to install the packages so you can say pnpmi and that should take a second great so I'm going to clear the terminal and I will turn around your developer sir and you should see that everything works fine so we can go here same as before we can say localhost 5173 and this is basically it I like how the Bare Bones project doesn't have a lot of things so you have to delete a bunch of files and Etc but in this case I'm just going to close the terminal and let me just talk about first about the things we selected so first one was eslint right and if you're not familiar eslint is like a spell checker for your code that gives you useful warnings in your editor from checking your code for problems like accessibility so let me just see if I can quickly show this if I go to routes page and for example I'm just going to delete everything let me just do something that it doesn't like so we can say whatever and you can see here we get some warning and we can hover over it so islint is saying accessibility pound is not a valid ref attribute and this is how swelker will lead you to the right way with accessibility and other useful warnings but in this case I can just delete this and close it so whatever if you're going to discover that eslint and typescript make a great Duo ensuring you don't do something goofy next let's talk about prettier so prettier is an opinionated code formatter you might find it does some things you don't like but it's a great trade-off considering you don't have to think about formatting your code and it's going to be consistent for everyone else working on the project I also recommend you enable format and Save which you can look up how to do for your editor but again let me just open this file so you can say heytron for example hello world and I can just press save and this is going to get Auto formatted and now you don't have to ever think about how to format your code and Etc because prettier just does it for you let me close this file and let's talk about playwright which is interesting so playwork is used for end-to-end testing and end-to-end testing might be awake what is that so basically you can test how your user might use the site using a real browser and you can check for example if some content is showing or test your registration or checkout process say for example on Joy of code I have posts and I just want to test if those posts are visible on the page so I can basically just click around and see if it works and next let's talk about another testing tool which is v-test which is a blazing fast unit testing framework so we test as it says is used for unit testing and what does that mean that means you're testing one unit of your code so for example you can use playwright to test your site using a real browser and see if your content works like I gave you in that example but you would use v test to test the input and output of the function responsible for sorting the content in some order right so that's basically what a unit test is and also want to show you that in the examples so for example here is the test we talked about playwright so basically this is just going to open a browser in the background which is going to run headless but you can also specify so you can see the browser and what's going on on the page and this just checks if index page has accepted H1 so that's basically awesome and here is an example I believe in Source index test test here is an example using v test so this is a unit test you can see it checks if Sound Works so if the function sums up 1 and 2 to equal three but alright let's look at the beautiful tree we inherited from scaffolding the soil kit project just close this and I'm just going to close all these steps so they're not distracting and let me just close these two so the first folder is the one created by swelke which is dot 12 kit we already talked about this but it's a folder generated by swellkit and it's safe to remove so we can just ignore this for now and if you're not familiar with the node modules folder here's basically where all your packages go so here leaves cell kit vid and Etc your binaries if you run something like pnpx this is going to get stored here in your binaries so you can run it without having to install the package globally if you ever done that let me close the null module cells look at something more interesting which is the source folder so this is the heart of your project so here we have routes which swellkit knows to map to a page so whatever you create here you're going to see in the browser there's also going to be another folder here which you're going to use to store shared components which is going to be lib so you can create that if you want and this is also aliased in swellkit as a special import so you don't have to do that convoluted trailing where you do dot dot and then slash Etc you can just say dollar sign lip and it's going to know the path to it you can also specify your own aliases so for example you can have an alias to your Styles Alias your components and Etc okay let me just cancel that out here are some files that are specific more to typescript so if you don't use typescript you can just ignore this but if I open app.ts this is used to add some type information for some special swell kit objects which we're going to talk about in later Parts you don't really have to think about this and I can just close this we already talked about app.html it's a template used by cellkit for your pages and here let me just show you so here it uses the favicon some meta tags and this is really interesting so it also has for you data preloading which is on Hover so it starts fetching the data on your page in advance it's well kit knows thanks to code splitting what the CSS in JavaScript is required for the next page and here you might see something interesting why is this swelkit body inside of this deck and this is basically to avoid some problems with extensions that inject themselves into the body this is just how swelkid avoids that problem alright so we can close this file and I already showed you the v-test one so we can skip that so here is the static folder and here you would place your images or whatever you have like favicon so basically it's nothing special here are your tests so I already showed you this for playwright you can place your test whatever it is because v-test is going to scan your entire project so you can put your test besides your component or in one folder that's really up to you so elk it really has no strict opinions on this so we talked about eslint and here is the eslint config file and it looks intimidating and you really don't have to care about anything inside here what you do might want to know is that you can extend this so you can add your rules you can disable rules and Etc let me just close this so I have a git ignore file if you're not familiar with this this is basically going to ignore files and folders you specify when you push your project to GitHub for example you might not want to leak your environment variables and Etc but yeah here is another interesting file dot npmrc so this is a config file for npm and it has this option here engine strict true and basically what this means is that it's going to refuse to install packages that aren't compatible with the version of node.js you're using but yeah that's basically it so you also have a prettier file here so you can choose your preferences you can say use steps for example I prefer not using semicolons so you can go here you can say semi false and then you can also pick some other options here are some good defaults in my opinion another interesting thing is if you go to package Json let me just go here so it would be really a noise if you change this to not use semicolons and we have to open every file and press save and format but instead of doing that you can go here you can just run the command to format your entire project which is right here so we just run format and this will run prettier for you same for linking so you can check your projects for errors you can also run unit test and Etc here are some really useful scripts for you to use but yeah let me just close these files and you already might know about package Json but basically this is where order package information is being kept scripts and Etc and even if you wanted all of these ignarly dot files here which is unavoidable in doing modern JavaScript development where you can have all of this inside your package Json if you want which would be kinda unmaintainable but that also obviously depends on you and then we have a player config which you will learn from reading the documentation because this really has nothing to do with circuit they just really make this setup easy for you to configure playwright and that is really fascinating so I can close this to have your log file here if you don't know what this is you can lock your package versions to a specific file so when someone else downloads the project they're going to get the same version as you have so that avoids issues and of course what we never do when we start a new project or whatever is actually read the readme which explains almost everything so this shows you creating the project how to install the packages how to start it and how to build it but yeah and basically read your readmies right so here we already looked at it but here is the swell config that we did by hand previously and it's exactly the same nothing special so we can also see the Veet config here which is the same as before it also has some extra things for tests to include some files nothing special so you can just close this and here is the tsconfig file so basically this extends the swell kit typescript configuration file you can also change this however you want you can enable path aliases here it shows you some useful information but that's basically it if you're newer to development you might be hearing some of these things for the first time but you can ignore most of them to be honest and there's really a lot of junk in these files and it really can be avoided because that's how mostly modern web development is done this is like nothing compared to a real project where you're going to have even more files so for deployment you might have a Docker config and Etc so that really gets out of hand quick so there's really not the fault of selkit but just the general JavaScript ecosystem so I hope this gave you a better understanding of these configuration files in general because you're going to see them in every JavaScript project but now you're a certified swelkit connoisseur if you're just starting learning swellkit and want to follow along you're going to need node.js and I recommend using vs code as the editor and using the swelled vs code extension so we're going to go to the node.js downloaded this is going to get npm for you if you're new to this or going to be able to install packages and I also highly encourage you despite me in the post using npm because it's standard I personally going to use pnpm please get pnpm save your hard drive because pnpm lets you reuse packages so for example when you start a new project you're not going to install the same packages all over again which is really going to destroy your hard drive and pnpm is way faster because of this so it just uses links to packages for every project so it's really super fast and it's really easy to set up so I highly encourage you to look into that so you're going to need vs code for the editor but you can use whatever you want of course you're going to need to set up the swelled syntax highlighting yourself so you're going to need this extension as well for reals code just grab this and you're going to be fine so for example if I press Ctrl shift X I'm going to get to my extensions and now I can type in swelt and I should get the extension so here it is felt for vs code you should install this and you should be good so let me just close this and here I just have a regular silky project you already know how to do this you can scaffold this really it's not important what you select because you're going to be mostly talking about routing but I'm going to use typescript but typescript is really optional and if you're afraid of typescript you can just ignore it so for example people really think that typescript is spooky thing but for example if you just see something like let's say variable and you see something with a colon number if you're not familiar with typescript you can just basically just ignore the type remove it right and that's going to be valid JavaScript so let me just close this another thing I'm going to set up is some styling so I don't ruin my eye so I'm going to use Pico CSS this is going to give us some nice default style so I'm going to go to get started I really going to use a CTN because I don't want to install anything right now I'm just going to copy this over Ctrl p inuitary is called open app HTML and here before the head ends we're just going to paste this in and I've already started a development server with pmpm run Dev so if I go to localhost here if I refresh it it's already updated so you can see Pico is in action here which has some really nice default styles for us another thing you can do is use stack Blitz if you want to follow along and using something like a tablet or whatever we really don't have access to all of this you can just go to sweltkit dot U this is just going to open a new staggers project and this honestly blows my mind because this uses node.js in the browser and it feels even faster than your local development but they are just going to set this up you might have to enable cookies because stack Blitz is some special secret sauce behind the scenes that uses web containers which is really fascinating but yeah you can do that as you see in Brave it tells me to enable web container so basically I just have to go here and I can put down the Shield or I can enable the cookies so let me just go here and I'm going to sell our cookies or decide and it should not work you're just going to restart but yeah this is a common problem with staggers when it's embedded for code example in some other size because it really needs you to access cookies but basically this is it you get a swirl Kit app super fast and that's it so let's talk about pages in soil kit silky uses file based routing where routes of your app are defined by the directories in your project so for example here is this URL and all of these parts are URL segments so example dot com this slash is going to map to routes which has a page.12 file so this is going to be your home and then if you want to go for example to post you have a post directory which has another plus page or swell file as you can see these routes are defined inside the source slash routes folder each director inside the routes folder can have one or more files using the plus prefix to define a page in swel could use a plus page.swell file which becomes a routed maps to a URL so let's create a default route I'm going to open the sidebar here I'm going to go to the source routes folder here we already have a plus page swail file that comes default when you scaffold the project I'm going to close the sidebar so let's just make some navigation so I can say nav autocomplete this is just empty narrator you can press tab to complete it so let me just create a link this is going to be our home so I can just say home and I'm just going to copy it over and we're going to have posts so I'm going to say post here I'm going to save it and I'm going to go here and you can see we already have this navigation that's home it's really important to understand the mental model of what a page is in soil kit because the page component gets rendered twice once on the server for the initial request and once on the client because of hydration which is just a fancy word that means adding JavaScript for interactivity to the page after the server returns their HTML document before I show you what I'm talking about let's just give it a H1 so we can just say home page and I'm just going to add a script here this is just a quick snippet I have so we can just add a script and here we're going to console log out hello so I'm going to say CL which is another snippet I have so we can just say hello all right so now pay attention I'm going to open the terminal so control dot is a shortcut for me but maybe something else for you or you can use the menu in vs code and I'm also going to open the console here and let me just adjust it so now I'm going to save this and first you're going to notice hello in the console here which is on the client and you're like maybe thinking okay but where it is on the server and because the client-side router already kicked in but for example let's say I'm the user I'm visiting the page for the first time so when I refresh this page is going to run on the server and on the client so let's see this in action I'm going to refresh now you see Hello on the server inside the terminal and in your browser I want you to understand what a page is and that it matches your mental model because it's going to save you a lot of trouble in the future a page itself is just a cell component which you can see for yourself if you press Ctrl shift I to open the developer tools and navigate to the network Tab and look at the response for the page so here we already inside developer tools so we can go to the network Tab and if you scroll up top we can see if we let me just clear everything also make sure you disable cache so you can see here is the document that server side render from the server if you go to the preview here is actually the entire HTML document but where is our page component so here is just a lot of junk for development you can ignore but here at the bottom is somewhere our page so we can find it quickly now here here it is somewhere let me just scroll to the bottom so here it is somewhere yeah so this is it so basically this might look weird to you because it doesn't look anything like swelt well at least the one you know about because this is what it means that swelt is a disappearing framework because well kit at the end of the day compiles to JavaScript so it doesn't even have to ship some runtime of course there is some runtime because at the end of the day if you look here swelters are component into a class class page extensive component so this is your component you don't have to understand this I just want to show you how this works and basically here is some magic with hydration and Etc you really don't have to consider yourself about but it's really useful to know about so remember a page is just a component in cell kit so let me just close this and also want to show you that if you look at the response of the page here we can actually go to the page source so here is actually your HTML generated you can see here is the script that's really responsible for hydration and loading the client-side router and enables client-side rendering once the page is loaded alright but enough of this let me just close this and I'm also going to close the terminal for now here just complaining about the favicon which you can ignore but let me just close the terminal and let's create another route and let me just do one quick thing so I'm going to go to prettier and I'm going to disable semicolon because I prefer no semicolons so I can just close that and let me just save it and they should all the format everything and Awesome everything works so I'm going to open the sidebar in our routes I'm going to press new file which is a neat trick in vs code so we can start creating a folder let's name post we can say slash and then we can say page Plus 12. and now we can just go here we can copy what we already have we don't even need this right now let me just remove this and just copy this entire part we can go here and instead of home page we can just say post page so here is our home and pose and it looks weird because of pickup so what I have to do in this navigation is going to create a URL I'm going to say Li going to place it like this let me just select all of this I'm going to create another one let me just do this I'm going to save it and now this should be working so you can see if you go to home and post everything should work great and let me just copy over this to post yes everything should work great awesome so you might be wondering what is the reason behind this weird plus symbol and basically it's just a silk it knows that this is a specific file to a route so what this enables you to do is collocate code so for example if you had a post component for example or some utility here you can just create a normal file here instead of having to use some weird names like underscore and Etc because cell kit is going to ignore everything that's not a route yes let me just close the sidebar I mentioned how pages are just components and just like regular components they're mounted and destroyed on navigation so let's see if that is true so I'm going to go to the home page and I'm going to add Back The Script I'm going to use the on Mount and on Destroy methods I'm going to say on Mount and they should Auto Import it for me if I press it like this so here I'm going to give it a callback I'm going to say console log I'm going to say mounted home page and then I'm going to say on Destroy I'm going to give it also a callback console log on mounted home page I'm going to save this and let me just copy this over so I can go here to post you're going to copy this and now we can just say mounted posts so I can press Ctrl D to select what's similar mounted and unmounted post page all right so here we're going to go first to the console let me just clear everything here and now I'm the user first time opening the page so let me just do this so you can see it says mounted home page and now when we go to the Post page you should say that it unmounted the home page and mounted the post page awesome so it says unmounted home page mounted post page the same is true when you go back because your pages or just components this also means that page transitions are really simple in swelkit which is a topic for another time but I also want to notice how the only thing that loads when navigating between the pages is the data for the page because it's using client signed rendering but if you refresh the page it's going to use server-side rendering so let me just show you what I mean if I go to the network tab I'm going to clear everything again and let me just refresh so this is the first time when you visit the page right so you're going to see that you get the entire document here so you can see here is everything you need but let me just clear everything and I'm going to show you something awesome so the first thing notice the data preloading we are going to hover over posts and it didn't load any HTML document right or did server side rendering at least behind the scenes but for example you can see it just loaded the component that it requires so you can see this looks very familiar and that's basically it but you can see here if we for example again do a hard refresh so revisiting the post page for the first time it's going to load everything let me just clear this I'm going to load everything you can see now you have a document here which has everything again and if I clear this and again going to home it's just going to load what it requires and don't forget to enable disable caching if you're doing this so you're going to get consistent results but yeah basically this is how this works and you might be wondering is the data pre-loading some magic that silky does and the answer is yes it's some magic but because swelkid knows the data required for your route it can load the CSS and JavaScript in advance and this is thanks to if I press Ctrl p and go to app HTML you can see this attribute on the body that's data swellkit pre-load data on Hover so when you hover over a link is going to start pre-fetching or preloading the data for the next page so I kind of want to show you how this is awesome if I go for example I'll go here and let me just create some styles let me just say H1 color aqua and you won't see this in development but let's stop the developer server inside pmpm run build and I'm also going to run preview so basically this is emulating like you're in production all right so let's build everything that's going to take one second and now the URL is different it's going to be 4173 so let's go to the home page so pay attention what happens now how awesome is this when you go to post it's going to load the CSS and the JavaScript required for the page amazing so you can see here is the CSS along which is scoped to this component and here is just the JavaScript which is probably oh it's not even minified interesting oh this is because I have this pretty print but when you remove this it's minified so yeah you get the smallest bundle size but how awesome is this another thing worth mentioning is that you can set preloading for the entire page like it is set in the app.html file but you can also set it for individual links and override it if you want alright so that was a brief and interesting tangent and a pack here in development mode so let's talk about layouts our two pages if you notice share the same navigation and we could create a navigation component and then we can reuse it so you might be familiar with this from other Frameworks we can probably make something like navigation and then we can import navigation from whatever right but really in cell kit this is sold using layouts so first I'm going to remove these Styles because we don't need them and let's take the repeating Styles I'm also going to remove the script block and let's just take this we're just going to cut it let's just save this in our post we're going to go to home I'm also going to remove everything here so how do you create a root layout you create a root layer by going to Source routes and then you can say new file and you can create layout plus well now we can just copy the navigation over and we should see the navigation is here and everything works but where's the content and you need to do another thing which is pass a slot so you can do it like this you can save and now you can see the home page and the post page and this is also a great spot to include your Global style so for example if I go to source and I can just create app CSS which is as close it quickly so you can create some Global Styles we can save body let's give it some padding and then I'm going to save for the title I want align High to be one and then I can say text transform capitalize let me just save it I'm going to close this file and now inside our layout let me just move it here we can go to the top we can create a script block and now we can say import so we just have to go on folder above and we can say app CSS and now when you save it you should see that things are going to get updated awesome and just like your pages the layout is going to run on the server and client but first let me explain to you what a slot is and basically if you're not familiar this isn't something silky specific but this comes from swelt which is a slot property which lets you pass anything you want so here I have an example of that let me just go here so here you can pretend this is our page so this is the root layout here we have our navigation we can obviously move the slot wherever we want and that's basically how that works so basically everything that you pass here is going to be shown so in remix this is outlets and I don't know what it is in other framers but basically that's how it works so you can include repeating content here like navigation a sidebar or a footer and it's going to be repeated for every child route so for example if we have a post route here is the root layout so if you create a slash post now we have a sidebar here and post and basically this is going to be the slot it's just going to show the other content so basically how this works behind the scenes in swellkit let's say for example we have our home page remember our page is just a component so when you add something like a layout a new slot is basically equivalent to something like this right so basically this is what it does and now we can just indent it and basically that's how this works so everything else is going to get passed as I said a slot lets other content through and as you navigate to a route it mounts the component for the page and unmounts the old component so one component is just going to be active for the route you're on so for example if you go to the Post page this is not going to be active you're just going to show the post page right another interesting thing is that if there's an error it's just going to render the error for that page and nothing else so if you really want to see how the secret sauce works let me just exit this component so in your dot cell kit folder this might look intimidating but don't worry about it so let me just see I think it's in the generated we can see here is the root.12 file for the pages so it really has some interesting things here that are foreshadowing but we can see here how it kinda works and you don't really have to understand so basically this is exactly what I've shown you so if it's just a single component without a layout then it's just going to render out the component but if it has a layout then you're just going to use the layout and then it's just going to render your component and if there's an error is going to show the error component instead and basically that's how that works so this is really fascinating what you're going to learn even more about layouts so I'm just going to close this and let's talk about the power of nested routes you can Nest layouts as much as you want so let's say for example I want a slash post so if I go here I'm already a slash post but for example I really want this kind of route where I have slash post and slug so how I have it here if I go to slash post and this is another beautiful aspect of file based routing because this is going to match the URL where your other content is so you're on post and this is going to be our new layout which you can create a nested layout for which so we're going to have a sidebar post and when I click on a post it's going to load the post on the right side and if I go here this works by this so we're going to go to post and we're going to go to the slug and this is going to show the post here but the true power of nested layouts or routing is we already mentioned how silky knows what data to load for the page which is awesome but another great aspect is that let's say for example something goes wrong here when we load the post instead of taking our entire app down only this part is going to crash and you're going to get a useful error message and know where to look to fix the problem so let's have a look how that works I'm going to go back here and let me just close all of these files we're going to need this and now we just collapse everything and go to Source routes post inside our post so this is the post page and let me just give some text here so you can say you can and let me just give a link so let's say for example that we want the user to create the post so we can say plus create you can create or edit your posts here so basically this is what you want to do and now you need to create a layout so we always have this sidebar here and when we click on a post it's going to load it here and we already have a nested layout so our navigation isn't going anywhere right and how awesome is that so I can create another plus layer.swell file inside source routes posts plus layout.12 Swift so let's do that I'm going to go here so here where our posts are we can say new file Plus layout swelt I'm going to close the sidebar and now let's add quickly some markup so I can say pause using emit really simple I'm going to create an aside I'm going to give it a H4 to say pause and now I'm going to hard code some posts so I can say nav let's give it a list you can say Li let's give it a link so we can say post one do it like that and I'm just going to select this Li Control Alt for me and arrow down is going to just copy over the code in vs code so I'm going to say two so right now nothing is dynamic here but we're going to see how that works later so we can just say two and now remember we need to include a slot because if you just save this we can see our post is here say one two and it's not found because we need to do something which we're going to do in a second so this is one two and remember how to include the slot we can just say Main and let's just include a slot so now we can see our post page create and let's add some quick Styles so now you can go here I can say Style post let's say display grid we're going to give it a gap of 2 RAM let's say grid template column so I really want the column to be 200 pixels and then the post to be 60 characters wide but you can set it to whatever you want and I'll just give it some margin top we can say 2 RAM I'm going to save this and now we should move this main so it's part of our grid so we're going to get this layout and how awesome is this also this is hard to see let me just zoom in a bit I'm going to do it like this let me just see yeah let's just zoom in like this so remember how I showed you here this slug so when I go here and I go to pulse one we somehow need to load this post and we can do this using a parameter so this can be dynamic like a variable and this is how we can get the pulse or whatever we want so we can create our child routes for posts that's going to be named slash post slash create or we can even make something like post edit and it will inherit the root layout and the post layout so first let's create that so we have that because when we go to create there's nothing here right so we're going to go to the sidebar and there we have posts we're going to create another child route we're going to say create and again you just say Plus now we're going to close this let's give it a H1 create new post let's give it a paragraph create a new post we can save this now when we go to this route now it's post create before we talk about Dynamic routes let me show you the real superpower of nested routes and I already told you how swelkit knows what data to fetch for a particular route but I want to show you how when one part of your app fails it's not going to take the entire thing down first I'm going to create a file you don't have to know about what it does right now so I'm going to go to routes false remember to create and I'm going to create a special file so you don't have to be concerned what it does right now but basically I just want to cause an error for the page and when I create this file I'm just going to with the circuit extension make this function and now let's talk about unexpected and expected errors so in swelkit when you encounter an unexpected error it can contain sensitive information so the error message and stack Trace is not exposed to the user so let's really see what this is so basically unexpected error when you get a really bad error like this like yikes and then let me just go here and I'm going to say import type page load just so it doesn't complain at us so let me just save this and you're going to notice something so first I wrap crash but it basically took everything down right so that's really not great it's not useful error message for a reason because as I said this is an unexpected error so swellkit hides the error message and the stack Trace but you can see the logs for yourself it doesn't hide it but basically this is just to protect you so what can we do so for every route that you have you can create a plus error.swell file so it's just going to get contained to that area so if we go here to create we can just say new file we can say error and now you already see something interesting so if I say boom like this and go here again I'm going to go to post create and just going to say boom here and it's not going to take your entire app down so for example I can go here let me just say yikes and then maybe I can give it an emoji let's say explosion and then I can give it a description something went horribly wrong but the blast radius has been contained to do this route and also going to show you something fun so we can say script here and I can import of page store from App Stores and this is how you use this information in your error Pages anyhow so page store has some information here is some snippet I always use so it's free and you can just use Json stringify so it's really just going to Output an object of everything that's available so we can use a store by selling dollar sign page you can see page has options like error message and Etc let's really see what's inside this page so if I do this let me just zoom out so you can see what's going on so you can see yeah is something horribly wrong as you can see here is the error message you can see it's vague on purpose even though we said here that it's yikes right so we can go here we can see other params routing Etc and if you want to Output this really you have an example in the sulky docs you can go here and then you can say page and then you can say message error message or whatever else you have you can even output the status if you want but let's really talk about our expected errors it is and expected errors are created using the error helper which says the status and renders the error swell component and Returns the status and error message so this is something that you import from cell case so you can just comment this out that's going to go here and I can say Throw error and it should import this from circuit now we can give it a status and then let's say message we can say yikes and let me just give it an emoji it's a speaker so let's see when we save this ah okay so now that it's expected it's going to show the error message on the page so this goes back to what I showed you on this last diagram which when you're on the slot and if something goes wrong instead of it taking your entire app down this part is going to be down and you know where to look so you know where to start looking for the errors so let's talk about Dynamic routes in swelkit let's say that you had a lot of posts and it would be really tedious to create a route with a slug for every post you'd have to create slash posts one plus page 12 and then slash post to slash page soil and it will get really tedious so instead of doing that you can create a route with Dynamic parameters that use a square brackets around the variable name so instead of being one two and etc for every folder you can basically just create this type of route where it's logged and it's going to catch everything here you can catch one two three four you can catch a banana or whatever else you might have so let's see how we can create such a route so I'm going to go to the sidebar and here in routes posts you're going to create new file but we're creating a folder so you can say slug and let's just say slash of course we need the plus page file so we can do it like this and now this is going to match our slot so inside of here I can just say pause and then let's just log out the params and remember how we have access to this great store from circuit so we can say import page from see app stores and I'm going to use a snippet here and I'm just going to save page here I'm going to save it and now notice when we navigate to our post it's going to catch this param which is one so it says params here slug its name is one and then we have all other useful information so if you go to two for example it says two and of course this data is the same but now I hope some years are turning in your head and you can imagine how if we have access to this lock here we can just pass it to a database or whatever function we have that calls some piece of data so we can dynamically render content on the page so right now if you navigate to any post the content is going to be the same but later when we get to loading data I'm going to show you how to use the dynamic parameter to show a post let's talk about more advanced routing in cell kit first let's talk about multiple route parameters so what are multiple route parameters you can use multiple parameters as long as they are separated by at least one character so for example let's say we have some image API so this is going to be I don't know for example image and then maybe you want 200 by 200 whatever and basically how can we get this as parameters so we can just put them again in square brackets and we can create literally a route like that and we can get the width and height and do whatever we need on the back end so here in our project this is starting to get a readable so I'm just going to collapse everything and I'm going to go back to routes and inside our routes I'm just going to create a new file I'm going to create an image folder and that image folder is going to have a URL segment with X we need a character right width height and inside of it since this is a folder we need to create Plus page sweld so you can see here we created an image folder with height which are going to be the params and now we have access to them so let me just close this and again I'm going to import the page from App Stores I'm going to create a title dimensions and then let's just output it so you can say page let me just save this so let's really use this how I said so we can go here and of course we don't need these brackets in the URL so let's say for example a user wants an image of the dimension 200 by 200 now we can go to that route and we can see dimensions and here are the params so we get the width and height and now you can do whatever you want with this next let's talk about optional parameters let's say you're working on internationalization and you have a lang slash above route with a required length parameter so for example if I'm here let's say I have English about but I also want to match it by default that is just about which isn't going to work so let me just show you that I'm going to go to the sidebar inside a row so let me just close everything here I'm going to say new file so I'm going to create a dynamic parameter length this is going to be about and we're going to have page swelt and let's just say about so now we're going to go here and for example I'm going to say English about is going to work but for example what if you want just this Default about is going to say not found so in this scenario this is where optional parameters are useful so to make a parameter optional we can wrap the square brackets in another pair of square brackets so if I go to the sidebar here where Lang is I can say rename and let's just add another pair of square brackets I'm going to save this and now I'm going to go here and refresh you can see that this matches I want to know that this is a simplified example because you haven't learned about some things yet to make change in the language work but at least you know about optional parameters in case you need it next I want to talk about rest parameters you might be familiar with rest from JavaScript and that's the same idea for routes in swelkit you might receive an unknown number of path segments in case we should use a rest parameter but be careful you do checks in your code because it could be anything so let me just really show you the idea behind this so here is a contrary example let's say we have some image API or whatever and then we have media and then we need path to file or whatever and then maybe this is some image API so the user can give of it and hide but basically this is an unknown number of segments right so we can use a rest path so we can say it like this you can say file and now we can catch what the user entered here and do checks that we need and do whatever we need after that so let's see how we can do something like this if I go here and now in the source again routes I'm going to create new file so I'm going to create a media folder I'm going to say slash and now since we don't know the number of segments in advance we can just say file this can be anything you want this can be banana or whatever right so you can just say file and then let's also say slash and we're going to create another folder of course we're going to say with and we're going to say height because those are just parameters right and of course we also need to say slash page as well so this might really look complicated but just give it a second to think about it but yeah we can just go here so now we have media file which is going to catch everything and now we have width height and our page which is going to be the page itself so same as before I'm going to import page from App Stores and I can see here rest parameters and now let's just output so I can just pre output the page so now for example the user navigates to Media and now they can say path to image and it can also give Dimensions so you can say 200 by 200 we should get a result so you can see here it matches the params so we get a file here path to image we get the width and height how awesome is this lastly let's talk about matching parameters so if you go to the Post route for example posts and you can say slash one this is going to match it but of course it's going to match everything else like one two three four banana and Etc but let's say we have something invalid like a space this should never be a slug right so how can we make this more strict and make sure the route matches a valid slug we can do this using matching parameters and to do that you just have to create a source slash params folder and you need to create a file that exports a mesh function so let me show you quickly how you can do that we can go here to source and we can just create new files so I'm going to create a params folder slash and I'm going to create a slug DS file and I'm just going to say export const match foreign matcher which is going to import the type so we're going to say param let me just do this and of course you need to spell this properly so you can say export and I'm just going to save this so okay now we need to return a Boolean if this is true and false which is going to involve some regex but don't be afraid because instead of using stack Overflow or whatever we can just ask our friend chat GPT so we can go to chair GPT which is my new best friend so you can just give it a prompt here for example we can say can you write a match function in JavaScript that just checks leave the param is a slug and it's going to say sure and let's see what it's going to come up with so yeah basically almost almost we're there I just want something simpler right and you can even show you how we can use the function which is amusing and just give it a second so it just ends and then we can regenerate it then we're going to see a much simpler answer so let me just go here and it's going to ask a new answer and let's see what it comes up with so it says match param and also that's basically everything we needed and we can just go here we don't even need to copy the function let's just copy the regex so you can go here you can say return we can just use the tragics and then we can use test and we can pass it the param all right so I'll check GPT is doing his thing over here let me just save this actually before I save it let me just go to one all right go here and if I refresh it everything works so now if you give it something invalid it should return a 404 because it doesn't match the route but it's not working and why is that we have to do one more thing so for example if I go here and then here in our routes where we use the slug so this is going to be in post log you have to say rename and then you need to use the measure so we can say equals slug or whatever else measure you have just save this and now we get a 404 not found let me just see this is true so we can go one two we can even pass it banana all right whatever one two three four and this should be valid but for example something like a space it's not a very Slug It should just say 404 not found alright sweet that's everything you need to know when it comes to routing in cell kit there's more advanced things to go over like group layout but first we need to learn about data loading as well kit which I'm excited about so look out for the next part in this part or the swellkit series we're going to be learning how to create API endpoints and loading data for pages in swellkit so here I have a simple Circle project which were at this point you already should know how to make and I just have some default Styles so you can go to your app HTML and here I have included some Pico CSS Styles which you can include yourself if you want and then I have some Global Styles which is app.css and then I just have a root layout here where our imported in Styles and I have some basic navigation here and that's basically it if you want to catch up and you don't have this project set up and here is nothing special just say hello and then you can go and run the development server so I can say pnpm run Dev and now we can go to 5173 and everything should look great before I get started I'm going to set up a database with Prisma and Prisma is really awesome because it basically instead writing raw SQL you're going to write something more that looks like typescript and this is a schema in Prisma which you can look at this example here here is how you define a table in your database you can just say model post and Etc and this is really simpler than writing raw SQL yourself for database I'm going to use sqlite which is really awesome because you don't have to set up anything it's just a file on your system meaning you don't have to figure out for an hour how to set up a database or sign up for things you really don't care about and I'm also going to show you how to see your database we're going to use some placeholder data from dummy Json so here it has 30 posts for us by default when you open the API so we can look here here are the posts so we're going to input that into our database just so we have some data to work with but yeah let me close this and let's get started so I can go here I can press Ctrl C to stop our development server Ctrl able to clear everything now let's start and initialize the Prisma database so I can say p and PX Prisma init and this is mostly just going to be a speech run how to set up Prisma so we can use data source provider this is really an awesome and quick way to set up sqlite with Prisma providing this flag so you can just say enter and this should take a second and if you look here what happened this created a Prisma folder with our schema so you can really ignore this part to the top we're going to write our schema here and also created our EnV file let me just close the sidebar so you can see what's going on and here is the beautiful part about Prisma so this connection string here you can replace this with anything later you can create a database on Super Bass for free right you can just drop in the connection string here and you don't have to change anything else Prisma supports many databases from postgresql SQL to even mongodb I think but before we get to writing our schema we also need to install the Prisma client which is going to let us interface with the database so I'm going to say pnpm I we can say Prisma client and I'll give it a second awesome so now let's create our schema so I'm going to close the terminal let's close this and now we can start creating our model here and model just means table model post and I'm going to give it an ID and also if you want this Auto completion you can get the Prisma extension from vs code but you don't have to so you can just say int which is a built-in type ID is also built in and also you can see how you get this great Auto completion thanks to typescript we can just say Auto increment and of course we're going to make this up I just took this from the Prisma example which also had this created at timestamp which is a built-in date type time we can say default now so that's how simple that is we also might want to know when it's updated again we can use the same thing but here is a special updated ad and now we can create our own fields so we can go here and basically this is really intuitive you're right okay title is text what is text in prisba it's string of course and now we can just say content or body string and if we give it a question mark it's optional because you might want to create an empty pose which is fine for the slot we want to beat unique so you can just say string and we can also make it unique using this so we can look this up using Prisma which is going to be really simple and then we can also have a publish field so this is going to be a Boolean simple as that and we also can give it a default value which is really awesome so you can just say false and now we don't really need to even think about this field and now we're not going to save Prisma is going to format this file but before we create the database let's create a seed file so we're not going to need this schema anymore we can close this let's go to Prisma I'm going to say new file seed TS you can say import prismacline this should auto complete for us very nice we can say cons DB new Prisma client and now we're going to create a type post which is going to be matching the post from the dummy Json response so you can just say title string body string and we can open it here on the side so you can see here it open which is awesome so as you can see here it returns an object with a post array and this has for every post ID title body we don't really care about ID we're going to create this ourselves and these are the things we don't care about and that's why I only created this type for title and body so you get great total completion alright so now let's fetch this pose so we basically let's copy this URL because we're going to need it we can say async function get pose and now I can say const response await Fetch and now I can just copy over this URL and now we can the structure pose because this is what it Returns on the object right calls post from a weight response Json and now we're going to return the pose and if I save this you can see one problem here is the returns promise any so we don't really get the type back and that's why we created this type so in typescript we can say s post but this is just a single post we have to say hey this is an array of posts awesome and now if you hover already as you can see it returns a promise which is of type post as an array so that's really not complicated and I'm also going to create another function that's going to be slugify so as you can see here this is this long title and I want to create slugs from our post title which would be really convenient if the API had this but it doesn't so you have to do it ourselves you're not really need to import any other library because it's really simple to create such a function so you can say function slugify it's going to take in some text which is going to be a string and it's going to return that text and let me just make this easier to read so we can just say text replace and now we can give it some regex and then we can also Define what it needs to replace so you do it like this and you say Global so it's going to take into account everything and now we need to Target by space so we can say this so this is going to Target every white space and now what we want to replace it if we can replace it with banana or whatever but let's just say we want a dash and next we want to remove any characters that are not letters numbers and Etc so this can be punctuation some special symbols or whatever and you can chain this you can say replace and now we can also specify our regex and let's just say we want to replace it with nothing so let's start writing the regex here we can do this matching thing so we're going to match a lowercase to Z a uppercase to uppercase Z and then we also want to match any numbers but of course this really isn't what we want we want the opposite of this we want to match anything that is in this so how do you do that you can specify it using a carrot symbol you can do this and now this means hey I'm going to match anything thing that isn't here and also for the last part we're going to say to lowercase because we want this log in lowercase and let me just show you how this works so I can get this part and I'm going to go here I'm just going to open the developer tools and let me just clear this and this is complaining because we really have the developer server so actually this is really annoying let's just go here and let's go to the console and now I'm going to copy over this call so of course let's give it some text so you can say it's Ami Mario and now this will create a slug so you can see it should replace this and it should fill in the dashes here so if I press enter and good thing that we don't do because we made a mistake and this is why regex is so tricky so you can see here we need to preserve the dash right so we also need to say Dash here and this should work so we can see it'sami Mario okay so let me just also give you another tip if you go to regexer you can actually learn how this thing works so if I take in this regex let me just paste this in and let's also just give it an example and you can see it's going to not only match it what you want right so you know it works but it's also going to give you a description so this is really a negated set and this is going to give you all the description here and maybe you can also Shad GPT which would be really interesting right but yeah really that's a hot tip so we can just close this for now and let me just clear this I'm just going to close this so basically now we have the slogify and now we're going to Loop over the post and add them to the database so I'm going to create a function async function main you can name this whatever you want because we're just going to run it so before we forget let's just invoke it so in the script runs it's going to run so now we can get the pulse we can say cons posts await get post and you can see we're also going to get the types here which is really awesome so let me just briefly show you how simple it is to add a post in Prisma so what we can do is we can say await DB post we can say create you can see how awesome this Auto completion is you really have to think about it or look at the documentation and now when we pass it here this this is why Tasker is awesome because you can just say Ctrl spacebar and then we have our option you can say Okay select doesn't make sense here have only data so I can do that you can see here is an object and now you can also go deeper and I can press Ctrl spacebar again and you can see here is the awesome Auto completion for Prisma so you can see everything you can enter here but basically what we have to add is the title which is going to come from the post title and don't worry this is going to come from our roof just want to focus on this so you can say content Paul's body and remember we have to use our slogify to create a slog so you can just say slogify post title and now we can create the loop and when I'm dealing with async things like this I need to Loop over I honestly don't like using map because the code looks really ugly because you have to wrap it in promise all or whatever and it looks really ugly and for this reason I prefer something that's more readable and that's a four offload so you can just say four cons post of posts and I can just do this and now we can move the code here just like that and now we can see here we have Auto completion from post and you can even destructure this if you want since we have types you can see body title if you want to do that but I honestly prefer legibility when someone else is reading this code and basically that's everything it's not that bad right so you can just save it and now before we can run the C script we need to add a save script right so we can just go to package.json I press Ctrl p and now we're just going to create a Prisma script and again this isn't some magic knowledge this is just from reading the Prisma documentation they have a nice section but one thing that isn't nice is how they describe seating which isn't going to work in cell kit because we're using type module which is using native JavaScript module and this is going to work with TS node but here is a simple solution to that so you can just say Prisma following just like they have it in a documentation now we need a c script and here is the part that's just going to work like a magic so instead of using ts9 highly recommend it we're just going to say pnpx we're going to use the wheat node package which is going to transpile on the Fly the typescript file so you can just say Prisma we need to point it to the C script cpts and this is just going to work now we can run the migrate command which is going to create the database from the Prisma schema and run the seed script if it finds it so now we can open the terminal I'm going to press Ctrl L to clear everything and now we can run pnpx Prisma migrate so it's Dev name and now you can give it any name you want this can be banana but I'm just going to stick to init as I show in their example so this is going to create the database from the schema and it's going to run the seed script so let's press enter and should take a second awesome so let's close the terminal so I can show you what happened and also close the seed file you won't ever have to look at it again so here it created the sqli database one which is really awesome and you can see here we created a migrations folder so every time you make a change to your database you're going to have a migration here so here is underneath and here is the magic source so it creates the raw SQL code for you this is how Prisma works and it's really awesome so let me just close this another way how you can confirm that everything works Prisma has a graphical user interface which you can use to check out your database which is called Prisma studio and it really gives me phpmyadmin Vibes which is really awesome so you can just say the npx Prisma studio and it's going to open it in your browser and here are the posts but what you're going to most likely see if you open it for the first time you're going to see this view here are going to be older tables you can see here we have posts and now when you view post here is the timestamps updated add title we have the content and now we also have the slug oh but of course I made a blunder and I'm really glad this happened so I can show you how you can reset your database so remember how we corrected the mistake not packing Json in our C script I really forgot to enter the dash here right so literally small mistake but I'm going to delete this in because it's going to be awesome so let me just save this so what you can do of course is you can delete everything but you can also say here pnpx Prisma you can say migrate reset are you sure you want to delete this you can just say yes now we can delete the migration and now you can press Ctrl L to clear everything and let's just do the migration again so we can say pnpx Prisma migrate so it was Dave name in it let's do this again awesome so let's run pnpx Prisma Studio which would open it in another tab so I just close this and let's see if this works this time and also now we have our slugs one last thing we have to do is actually export a database for use in our circuit application so for now I'm just going to close Prisma Studio I'm going to close this API and let me just close this close the C file I'm going to collapse everything just so we know where we are right so you can go to source and here is a special folder we can create which is aliased in soil kit we can just say lib and now we can create a database TS file and inside our database file we're just going to do the same thing we did in the seed script we can say Prisma client from Prisma client you know we can create the database again new Prisma client and adjust default export it awesome now you can use this anywhere in our app let's talk about API endpoints you probably used an API like dummy Json so for example if I go here and look at all the available endpoints I can see here is the products cards users and posts endpoint I'm interested in and let's go to the post and what really happens here right so to understand this we need to open the developer tools so you can say control shift I and let's go to the network tab also make sure you disable cache and now when we reload the page you're going to see some junk which is not important but here's the important part what is actually returned here is the document post so we can see here the headers preview which is the Json that got back so here all the posts so this is basically what we can fetch and show or do whatever here is the raw response so if you go to the header here's the request URL the request method which is get the status code 200 okay but how does it know right that this is like Json and it should show it like this basically this is because of the response header so we can see the content type on the response header is set to application Json and also another thing is that you might not be seeing this like this and the reason is because I'm using an extension so if I go to extensions and this is true for all chromium based browsers which is really surprising to me that the current year chrome doesn't have this and Firefox had this for years so we can go to extensions you can get an extension like Json viewer so this is how it would look like for you if you don't have any extension let me just go here I'm going to refresh the page so you can see now that this matches the exact same raw response but basically we can just get an extension use Json viewer if you want but you can use anything else I'm just going to refresh it and also if you're curious you can go to the settings here and I'm using this Panda syntax theme so I can close this and this looks great all right but where am I going with this basically what I'm trying to say is that swellkit also makes creating API endpoints simple and in do that by creating a special plus dot server TS file that exports a function that corresponds to a HTTP verb which is get post patchbook delete or whatever else that function takes a request and returns a response and if you don't know about HTTP request methods where you learn about it of course on mdn so you can say HTTP request methods you can go here you can open mdn and now you can see the explanation for this you can see each one and this is how you learn and this is a great thing about cell kit because we're going to spend more time learning about web standards on NDM than actually reading the circle documentation alright so let's create an endpoint so to show this how this works basically what I'm going to create if I close this so remember we have our here development server which should be running and now I basically want to create this endpoint I want API newsletter and right now it's not found but let's see how we can create it so I'm going to open the sidebar and in Source routes I'm going to create a special folder API slash newsletter this isn't convention you can name it banana or whatever you want in some Frameworks this is convention that you have to have an API folder but I'll just use it to know where these type of files are if this is some API that's used across the app so here in routes I can say new file so you can start creating some folders I can say API newsletter and then you have to create a special plus server TS file and now we can close the sidebar and now we can create the functions that match the HTTP request methods so we're going to create one that's API newsletter this is going to be the get request and also we're going to create a one it's going to be newsletter post request and how do we create it well we just say export const what we want get right and we're also going to use our request Handler type if you press enter it should Auto Import it or we can do this and now we can say async we didn't really have to and here is an event which comes by default so we're going to talk about this in a second so we're going to do this and let's just return some text right so remember how we say that it returns a response and we actually looked at the response in the Network Tools so you can say return new response and you can just return anything and also see this awesome type completion you can see body and the options you can just say hello and now if I save this it should return hello and if we look at the network tab you go here just refresh here is the newsletter and this looks familiar right so we can see a request method status code content type text so basically we can infer that the browser does this by default if you don't Supply anything so you don't have to specify it yourself and the browser is actually smart enough to understand the content type in most cases I also want to talk about the response obviously I'd be thinking about this you're seeing this for the first time okay I can probably learn about it in the silky dog wrong you're going to hear me talk about all this time about using web standards and response is a web standard so you can go mdn response you can open mdn you can see here the description and now we can go to the Constructor right so here is what we're using actually right new response you can see okay here is the body options but of course if you're using typescript you already know about this because you get awesome Auto completion but you can actually learn more about it here you can see what you can pass in so you can pass a blob array buffer I never use these things to be honest I use blobs array buffer no idea what this is ETC yeah readable streams this is something cool right but yeah this is really awesome and you can learn so much not just about cell kit but the web in general which is transferable knowledge all right but let's look at mdn as these options and let's create the options ourselves so you can just create them here like this that would be fine I just want to create a separate one so it's more readable so I can say const options and this is of type response init which will be available globally this really isn't important I just want this to have Auto completion so if I press Ctrl spacebar I'm going to see ah header status and Status text and how awesome it is so let's create our own status right we can say 418 which is going to return the depot status which is a hilarious meme in web development and then let's also specify some headers so we can take the mean to the next level and now we can give this whatever name you want like right this is like the part about learning and playing around like all of this looks serious like like your life depends on your drive but you can just play around and have fun so I can just name it X and what does X do of course X is gonna give it to you now we can pass the options here let's just save it and now when we refresh the page you should see here oh here is our status code and what is that status code you can see 1400 I'm at Depot you can learn more about this on mdn the origin of this joke and we can see something interesting here so here is around header X and what does X do X is going to give it to you alright so this is awesome but let's say for example we want to subscribe someone to your newsletter or you're using some other API so we can create a post request and let me just close this and now here we can just go to our post so basically we can use a form we can use the method type post and this is going to Ping this instead right because when we visit this page it's going to trigger the get but we want to trigger the post which we can do using a fetch request which I'm going to show you in a second but yeah let's just do that so how do we do that export cons post and you can say request Handler which would be the same type and let's just say event I'm just including this so you know that this is what you get by default even if we use it or not but in this case we're going to use it because we can get something interesting from the event which is the request so let me just show you that so we can just say it's going to be the data from the form right because we're going to submit it so you can just say data horizontal request typescript help us out so you can see here's some interesting thing which we're going to talk about later so we can just say event request you get the access to the request and while it's on the request form data beautiful so you can get the data and now we can get the email from the data so let me just move this up so how do we get this and basically this is also something you can look up on mdn the form data and how you work with it and you're going to find out that you get a value from form data by using the get methods you can say get and you're going to have a field which has a name email right and then here is some logic so you can subscribe you can subscribe the user to the newsletter but here we're just going to console log out the email when we submit it all right so now here is the interesting thing so remember how we had new response so basically we want to return Json and I'm just going to create a new line so this is more readable so basically we need to stringify first whatever we get so we have to say Json certified or some experts will say we need to serialize it okay so to do that and now we're also going to return our success true so basically when we get this response we can show a success message to the user right so we're going to return a success true because this isn't going to get returned if this fails right it's just going to explode okay so now for the header this is important we can say headers do it like this actually you need to rename it and now you set headers like this and again you'll learn about this also in mdn how do you set headers so you can say content type this is the same thing we've seen in the network tab and what do we want application Json and we also need to match it because this is another one we need to click like this and when I save it it's going to format it anyhow so that all goes through the window which is really awesome so yeah we can do it like this and now we just need to use it so how can we do this let me just go to the sidebar and here in our routes I'm just going to open the default page so now let's pretend that we're trying to make a sign up right so we can say H1 newsletter we're going to have a form and we don't have to specify an action this can this is by default get actually not an action this is the URL the method we're going to have to specify which is default get but we're going to specify post but actually we're going to use JavaScript here so we don't really need this but you can also get this from the form even if you use JavaScript but let's keep it simple I'm just going to remove this I'm going to have on submit and I'm just going to use this handy thing from cell prevent default and now we're just going to create a function subscribe so here instead of submit you say subscribe and default is going to be submit so you don't really need this let me just go here and now we just need an input it's going to be of type email and just say yeah type email we can just give it a name this is really important this is how we get the value from this thing so we can just say email you can even remove this of course introduce some semantic markup in your HTML and let's just create a script tag and now here is the more tedious part because we actually have to do this tedious part where you have to fetch the endpoint and Etc and that's why swelkit has another more awesome way of working uniforms which I'm going to save for another part but for now we're going to do this I'm going to say async function subscribe and it's going to return an event which is of type event so now we can get the form itself remember we can say event Target or you can use this but I really prefer this and after paste typescript we just need to say hey this is a HTML form element to treat it as a form element and now we need to get the data and remember this is what we get here right when we pass it back okay so how do we do that say const data new form data Ah that's interesting right so this is something also you can look up on mdn and we pass it back the form and now this is going to return the form values right which we can use and remember now we need to Ping a rainpoint how do we do that well we use fetch oh wait fetch what we want to Ping API newsletter and now we need to give it options right so here is an options object and now we can say method post ah how awesome is that and now for the body we return the data for it so let me just save this and again now we're going to return this data from the form whatever we passed in and you can also have values here that you can bind if you want this is honestly way simpler and closer to the web so this is what you're going to get here from the form data remember we created this form data here how awesome is this and now we have our own endpoint because we have an actual server and we don't really need a entire server we can use serverless functions from a cell which is actually perfectly suited for this because you can spin up one action at a time than having to have some server constantly running in the background so now we can get the email and this is going to log out the email and you're going to see the in response if it's successful you're going to see a success message alright so let me go to localhost by 173 here is our form I'm just going to move it here and now we should see this logged out on the server if I open the terminal here so let's just give it an email here say that I want to subscribe and actually let me just open the network tab here so I'm just going to press subscribe and you see ah here's the email right okay and now you can see here is the fetch request how awesome it is so now we're going to go here you can see it made a post request to API newsletter and now we can see the payload the preview it Returns the success and you can return whatever you want and now since you've done the fetch here you can go even further you can take this from the response and then you can update some State inside your app if this return whatever you want right and then you can show whatever you want to the user and how awesome is this and you can use this in many different ways so for example if I go to even my site you can see for example that all of these posts have view counters and basically that's done by having an API that just pings Super Bass so it just increments the count in some database whenever someone visits a page and this is how you can use an API endpoint whatever you need to hit some endpoint or whatever an API input is really useful and again I want to repeat the install Kit which is going to be on another part we're going to explore a much better way with working with forms in cell kit alright so this was just an introduction to API endpoints but what I really want to make I want to make an API post endpoint so you can go to API post and this should return all the posts from a database so you can use it across our app and this is what I'm going to do next so let me just close this and let me just keep this open let's close the terminal so now I'm going to close this and we can close this so now we're going to create another route so I'm going to go to API and I'm going to say new file and this time I'm going to create a post folder I'm going to say plus server TS and now we're going to use Prisma to fetch the post from our database and return them as Json so we can use them it's going to be exactly the same as the dummy Json API and later we're going to even enhance it so I can show you how you can make your own API more interesting and special alright so let's close this and now if you use the circuit extension you can just use kit and you can just say kit endpoint isn't going to give you a much quicker snippet you have to type all of this out so we can say export cons get and again we can just import this request Handler they should input it here and let me just instead of returning this I'm going to show you something so we can go here and now we just need to use Prisma to get the post and how do we do that well first we're going to import our database remember we created this DB from and this is aliased automatically for you lib database see it already knows and this is by default in circuit and you can also Alias other folders if you want okay so how do we get to post and this is going to be simpler so we just say cons post and now we need to use Prisma so we can say I'll wait DB post find many and that's it this is going to return all the posts and I'll remember how we said that we need to return so we can say return new response and remember how we had to stringify and Etc to return on Json response well this is so common in fact that circuit has a helper function for you so you don't have to do this so you can say return Json if you press enter it should Auto Import this from circuit so I can place this at the top so now you can say return Json now you don't need to do any of that now you can just return the post I can save it and now this should work so now let's go here you're going to refresh this and now we forget to post awesome and is the almost same exact thing like you get from dummy Json and here is our database so remember we had a created updated title now we get the slug also also we get the published Etc if that's what you want and here are all the posts that we had in our database and now we can go here to post we can see again same like that other API right we have our craft method status code here is of type Json we can go to the preview exact same thing here is the raw response right and how awesome is this so while I'm here I want to explain the event order to you because it's very important and you're going to see this across your entire cell key deck when it comes to loading data and Etc so what I'm going to do I'm just going to use an event here and then I'm going to console log it out so I'm just going to say console log event and if you're using types your course you can just structure here you already see all the options here cookies fetching Etc but let's just do this and let's open the terminal let's save everything and now when we reload the page we're going to see how here is some interesting things here so you can see so this is a method to get and set cookies in circuit then you also have fetch which has super powers which you're going to see how it works in a second so this is going to give you extra features like inheriting cookies and authorization headers for the page request it can do relative and internal requests on the server and it's also going to prevent additional requests because it inlines the response from HTML which really doesn't mean anything but we're going to see how that works in a second we also of course have params of the current page so remember previously when we had slug or whatever is going to give you those params we already seen how the requests works so it's going to give you the original request object the root has the information about the route so if you go here is the request there's a lot here's the route API post here's the URL so you can get whatever you want from here same as you can from that store that we used previously if you remember from the last part and then you also have another interesting thing which is a way to set headers so this also returns set headers which is right here so you can set the headers for the endpoint or for the page so let me actually show you an example of it and this is going to be really cool so we can go here and again we're in our post endpoint and now remember how we said that this should find many I'm just going to remove this here I also want to get a random number of postage time so you can see that caching works so you can specify to Prisma take and now we just need to generate a random number between 0 and 30. so we can say math round because it's going to return a float or whatever so you can just say math random and now we need to multiply it by the number of posts so this should always be random and we're going to fetch this post and I'm going to show you how this works and now here is how simple it is to set your own headers so from the event we have set headers and now you can specify your headers again cache control and you also learn how to do this on mdn so you can say max age is going to be 60 seconds so this is going to be fresh for 60 seconds and whenever you make a request to this it's going to Cache it to your disk and show it to the user so you can go to mdn HTTP caching they should open the HTTP caching link so you can learn everything you need to know about caching of course all right well before I show you that let's first talk about how we can actually show the data on the page alright so let's see how we can show the data on the page and this might look familiar to you because you're going to use client-side rendering and this is how you've done it in the past in react View and soiled before swell kit first I'm going to remove all of this code because this is just an example so you can just save it and then I'm going to add a script like this and now I'm going to create a function to get the post so now we can say const response I can say await Fetch and remember here is our API post so if I go here and just copy this over if we go to API post it's really just like any other API we can ping this so we can return some data nothing special here so you can just go here we can say const and thankfully press my generator is the type for us so we can get the post like this we can specify this is an array of posts and I can say a weight response Json and let me show us clearly like here and I'm just going to return both so now that we have this promise we can use a special a weight block from swelt to get the data and show it to the user so I'm going to go here I'm going to say H1 post so if we save this we can see here are the posts and now we can start using the block we can say I'll wait we have to use the promise get pause and now here you can set the loading data this is only going to show for a brief second because it's really fast and now when you have the data you can say then you can name this whatever you want I'm just going to name it post I'm also going to use my snippet that I used previously just so we can see what's on the page and now in case you have an error you can say catch error like this and I also need to close the weight block you can do it like this and now we need to say p you can output the error message in case you have an error okay let's save this and you already seen this took a millisecond and now okay one two three four so you can see we got a random amount of posts even though there's 30 posts and remember this is because previously we use take and now we use math random so now remember because we set the cache control header this is going to be fresh for a minute so no matter how much you refresh you should see 25 posts so here you can see here is 25 post and the way you can break this spell if you go to the network tab since we disable cache if I refer this right now this should refresh with a completely random set amount of pause let me just go here so here you can see it returned 21 if I refresh it again is returned 11. and of course you shouldn't rely this in production you should use S max age so you get it cached on the CDN so for example if I go here to post let me just see Max age 60 so you can see here it's cached and it's also going to say that it's red from disk of course let me just enable it like this so we can see the request you can see here it says disk cache so now when you open it you can see 200 okay from disk cache and when you're using a CDN in your header is going to have a header here that's going to say hit for the cache and you would set max age to zero of course if you're generating a completely static side generated site you really don't have to think about this when you upload it to something to your cell they're going to set the cache to Forever Until the next time you redeploy or whatever so basically you would set something if you're using server size rendering you would set this to public you would set max age to zero and then you have X max age 60. so for example if you have a deluge of traffic you're not going to hammer the servers it's going to get cash by the first person it might take the initial response more time but the subsequent responses are going to be much quicker so this is how you set the cache control header if using server side rendering and want to Cache something on a CDN but yeah I can just revert it to what I had before just as an example and that's basically it and also let's actually display the post so I'm going to close this and let's go here oops I'm just going to remove this and we can just use Google swell to Loop over the data and you can also see the caching in play if we let's see do I get auto complacer awesome we can just say showing so you can get the pulse length so showing amount of posts and then let's just Loop over the data let me just create space here so it's easier to read we can say each post as post and now we can close the each here and now we can just display so you can say UL I I'm just going to show a link so you can just say slash post this is what you're going to use in the future and now we can say post slog because remember this is why we created this log so we have here to visit the post and we can just say post title and of course if you want to be clever you can destructure it here since we have type completion you can see all of the things that are available to you so you can say post title and Etc like this slug title and now we can even remove this and now when I save this showing 25 posts and this should be cached showing 25 posts but remember we can always break the magic spell if we go here disable caching and now it should always return different data how awesome is this all right Fred so we've seen how we can show data on the page using client-side rendering but this comes with some problems for example here we have posts and really want great SEO and now when Google visits us or the gold bing is going to have problems parsing this JavaScript of course search engines can parse JavaScript in theory but it takes compute and really is Google going to waste resources on you so really don't believe those fairy tales and people tell you that it's fine to just use JavaScript it's not for many reasons because if you want great SEO you have to use server side rendering so let me show you what this means if you go to view page Source here you're going to see loading let me see if I can zoom in yeah so this is the only markup you're going to see and why is that available because we're using client sign rendering and if we go to the network tab I'm just going to refresh this and let me just go to the document here and this is the only thing that returns so this really isn't server side rendered so basically you're just getting an empty shell HTML file and whatever has to load here after the fact it uses JavaScript or swelt in this case which is why when a search engine comes here unless you can execute a JavaScript on your page and this is why you won't get great SEO because this is what the search engine is going to see unless it's able to execute JavaScript on your page downfall of this is that the JavaScript has to load first before you can even start fetching the data so it does a round trip right if you're making a dashboard or whatever like who cares right but for example something like post here or Etc where you want great SEO server side rendering is a must almost using server-side rendering is just a much nicer user experience and is going to avoid loading Spinners everywhere so instead of using client-side rendering I want to take advantage of serious side rendering in circuit and fetch the data before the page loaded which is going to result in a faster and more resilient app alright so how can we do this let me just close the developer tools and also going to close this view source so how we do this in swellkit a Page Plus wealth can have a sibling plus page TS file that exports a load function which returns data for the page and nothing else so let's create that file I'm going to open the sidebar in here in Source route so remember here is the page resulted root of routes you can create new file Plus page the s and now we need to export a load function so we can say export const load the type is going to be page load and it should Auto Import it for us which is nice we can just say async it also takes an event right so you're going to see this everywhere when it comes to data loading and now we need to do something special we need to use a fetch method from circuit so it understands the relative paths on the server we talked about this before if you remember so you can say const response await fetch and now we can just point it to our API so you can say API post and now we're going to get the response I'm going to use the pose from Prisma which is going to Auto Import for us which is nice now we can say I'll wait response Json and now we just return the data so you have to say return return an object and now we can return the posts the posts are going to now become available to our page inside a data param so we can see if we go here I'm just going to remove everything here and now we're going to start by creating a script again and I'm just going to say export let data and this is already typed for us which is really awesome because swelkit here generated the types post here and now we can use those so now we can go here and we can say page data and this is the only thing you have to import here so now if we save this and let me just however you can see this is already type which is really awesome all right so now we just need to use this data so we can just say post and again we're going to do the same thing I'm going to say showing post actually post length uh it's data post like my data post length posts okay sweet so now we can Loop over it again I can say each data post right as post and now we can close it here and now let's just say UL Li again we're going to use the link post so we want the slog if you remember post Slug and you're going to use the post title all right so let's save this and we should see our data which should be server side rendered awesome and again we can just refresh it we're just going to get a random amount of posts so now when we go to the network tab and let me just refresh this you can see we actually get the entire document so here you see 11 Post here you see the same thing so now when Google or the legend being comes around he's going to say oh here are some poles okay better in this and boom bam thank you ma'am now your number one ranked on Google or whatever congrats and also another thing I want you to note is that you can't find a single fetch request here so if you try you couldn't because why it happens on the server right and you would only see a fetch request if you navigate to some other link because silkit at that point as you learn in another part becomes almost like a single page application because when you first visit the page there shouldn't be any links right so let's see if we go to post so even if it says not found now if we go and preload home you should see here is the fetch request because this is basically client-side rendering but if you go to home and your first time visiting the page is going to render on the server and that's why there is no fetch request here and also another thing I want to show you how I mentioned and this is one that gets me all the time I use rarely fetch like this here because I'm using a database or whatever but because of that because you don't use it all the time you're going to get into this issue you're going to forget about this feature because fetch works on the server because it's fully filled so I'm going to have an event and this all looks great right okay great this is going to work great and now you save this and you get an eternal error which which is honestly not that helpful and now you're going to waste half an hour here trying to understand this cannot use relative URL if you like know about what I talked about this should make sense but if you don't then you're like okay what does this even mean like why does this work like just going to get confused so remember this is why this fetch is useful because it comes with superpowers so this is just going to work also remember how I also mentioned that fetch analyze the data and what does that really mean so for example if we go to the page Source here you can see here is your actual HTML ah but look at this here is the data itself so cell kit isn't going to have to do the same work again because it's just going to inlay this data and if nothing has changed it's just going to show the data so let me just close this another tip I want to show you when you go to page as well so this is great data post but honestly you're going to have a lot of things and it's going to become a pain having to constantly use data dot whatever but we can use reactive declaration so we can destructure posts so for example let's say you do const I'm going to say post from data so this is fine but this really wouldn't be reactive because when you update this nothing is going to happen so the next step you can do is use a reactive declaration which is a dollar sign but there's another problem this isn't valid syntax so you can just group it like this and now if you save it everything should work it this is now reactive when something changes it's going to update data so now we can go here and I'm going to say Ctrl D so everywhere where we use this I'm just going to remove it and let's also be a hot shot or you can say Select Title can remove it here save it and if you just close this and everything should work great it's great but sometimes you only want to run code on the server the plus page.ts file is great for fetching data for the page but also you have to keep in mind that it runs on the server and browser and it won't work if you need to use some Secrets or want to use the file system or database I'm going to show you this by creating a slug route that you'll get to post from the database using the slog parameter so I'm going to open the sidebar and inside our routes either going to create a new folder so I'm going to say pause I'm going to create another folder Slug and I'm going to create page.12 and let's just give it a title this should be post so now when we get the post here and go we should just see post you can see it's going to update so this will show the same but we want to dynamically show posts and this is also why we created the Slugs which is really awesome so now what we have to do is fetch the data on the page like we've done before so here in post we can go to Slug and remember we can create a page.ts file and we're going to see why this won't work in a minute but first let's just create the code so we can export the load function we can say export const load page load let's import it and now we can say async I'm going to need pyrams from the event because you're going to take the slug and we're going to fetch it from the database so now we can get the pulse we can say const post await if we start typing DB and press enter it should also Auto Import and this is why typescript is really awesome because it's really smart about these things in your editor so we can say DB post find unique remember because we specify that this lock should be unique so this is really easy find unique and now if we get Auto completion what are the options where right and now we can just give it a slug it also knows this select the unique identifier how do you get the slug from the param slot if you go here for example and you do console params you should see the slackback which we already learned in the previous part so now let's do some error handling so for example if there is no post we're going to throw an expected error if you also remember that from a previous part we're going to say throw error so this is going to be expected let's Auto Import error from cell kit so you can save row error let's give it a 404 and we can say post not found and now we can return the post if everything is alright and basically that should be it so now if you look at the terminal remember how we console log this out here let me just refresh it so you can see this is the slug so this is how we can fetch data as we've seen in the previous part when I tease this and now we're going to see why this doesn't work here you see we have an internal error so if you go here to our console you can see error prismaclient is unable to be run in the browser okay so how do we solve this like is this all code for nothing we're going to throw this away nope it's really simple as renaming plus page DS to plus page dot server dot yes so it's only going to be run on the server so if I go here I'm going to close this so inside your sidebar inside the slug folder we're going to rename page DS Dot serve the S and now if we go here we need to change some things instead of page load this becomes page server load so we can remove this type here let me just save this and I'm going to refresh and everything should work when you're accessing secret environment variables talking to a file system or a database you have to use dot server but by default just use plus page Ts for everything else alright so let's dynamically render the post and show it to the user so we can go to page swelt where we have the slog so now we can actually get the data right so let me just remove this let's say the script and now we can say export let data nothing changes here you're receiving the data we can Auto Import page data like this I'm also going to create a helper function that's going to format the date because we also return it from the database I'm going to say form a date it's going to accept the date it's going to be of type date and we're going to return this useful JavaScript feature we're going to say Intel date time format which is a really nice way how you can form our dates we can say English and for the date style we can use long and then we also have to say format and we need to pass it the date and that's going to be great so now we can show it in our template so I'm going to create a heading group and I just say H1 and I'm not going to use the fancy destruction because I really want to focus on this concept so I can say data post title as you can see we already have great Auto completion from typescript which is awesome and if you're not using typescript of course you can use JS doc so you just copy paste.js.com and here you will get the same awesome type completion so this is going to be the title and I'm going to add a subtitle and here is going to be the date so let's just do date post created at you know if we say we should see this and this really doesn't look pretty right but we can already see our post is working and I'm also going to have some content here and if we had some HTML or whatever in our post which we usually do right even when it's markdown we can just use HTML from soil we can say data post content additional choice for this page all right so now when you go to home his mother has always thought if you can see this is going to work the other post is going to work in all the other posts are going to work and now you're dynamically rendering data but let's also format the date so here we can use our utility function you can save this in a utility folder or whatever so let's just see how this is useful really simple to format it this way ah you can see January 10th and you also have other short I think you can use autocompletions again white ice cream is so awesome you just need to open the docs just see all the available options to you generate then let's say full this is going to give you the full idea we're using long so we can just keep it at that so not a lot has changed beside the file name and the types where the load function becoming page server load instead of page server in general whenever you need to create an API or make a HTTP request use plus server.ts and when you only care about data for the page use plus page DS or Plus page.server.ts in this section we're also going to talk about how your layout files can also load data your plus layout of cell files can also load data using a plus layout.ts or plus layout.server.ts file the same as your plus page.s cell files anyway wondering why would you do that well the superpower of doing that is that the data are returned from layout load function is not only available to that layout but it's also available to all the child routes meaning you can pass data like a hot potato for your routes let me just quickly show you how that looks like so here in Source routes you can see how we have the root layout here so if you want to load the data you can just create a new file layout.ts here and now if you have the circuit extension you can just do this but instead of page load the type is layout flow so this is going to get imported from you you also get the event the same as before and now we're just going to return a message and nothing else I'm going to say return message hello and now this data is going to become available to the layout page but also to your other child routes I'm going to press Ctrl p and I'm going to find the layout in your Source routes and here if you say export let data and we can give it a type layout data you can see this is imported for you and if you hover over it you're going to see that you're going to get the message which is awesome so now when you output it like here you need to snippet you're going to see message hello so let's take the same block of code and now we don't really need this here let's just remove it so now you can go to any child routes and you're going to be able to use that data so we can go to post where you have the slog for example to page swelt and now if you hover over this you should already see ah here it is the message and now if we put it here now when you go to a post you should see not only the post that returns for the page but also the message from the loader function from the layout this is really powerful when you have some data that you want to reuse so I'm going to show you how we can take advantage of that here in the post since we don't have a page yet we're going to create it but basically what I want here I want a sidebar that's going to give us a couple of posts and on the right I want to show the post that we've seen so far but also I want to recommend posts that are going to be the same as in this sidebar and we're going to use a layout to achieve that so you don't have to create a special file just to fetch the data for posts or whatever but first i'm going to remove this because we don't need it and I can just save this and we don't even really need this file so I'm going to find it here and I'm just going to delete it so first thing I'm just going to so I'm not blinded I'm going to go here let me just collapse everything just so we know our footing we have Source routes here is our post so remember when we visit post nothing here so I'm going to create a page dot swell file just to get started so you can just say pause and we're also going to include a paragraph We can say you can browse pose here and now we're also going to create a new layout so again under post layout.swell and let's just name it layout or whatever it's really not important for now because first we're going to fetch the data here and you can also see if you just give it a slot we should see everything else but we're going to get back to this first let's create a Plus layout.servert Ts file under post so you can say Plus layout server TS and why server TS because we're going to talk to Prisma of course so let me just collab this and we need to export a load function export const load the type is layout server load so this is going to get imported we can say async and again you get the event here if you need it just like before and we can just say const post so you can use Prisma if you press enter DB it should import it for us so you can just do it like this and we can get post find many because we want everything and now I'm going to specify the fields I want let me just do it like this so I can say select I don't want anything else I just want the title and I want the slot let's say true and I'm going to take four results nothing else and now we just need to return the post so I can say return pulse and basically that's it awesome so since we use this now this data is going to be available through our entire slash post route so we can go to layout 12 and I'm just going to remove everything here I'm just going to add a script export let data so we can get the data the type is going to be layout data which should be imported like this awesome now I'm going to create a layout like this we're going to have some basic styling let me just make space so it's more readable I'm going to create an aside is going to be a nav inside H4 we're going to have posts and now here is going to be some list and now we're going to Loop over each of those posts so you can see each data we have types here data posts right data post s slug title so sometimes this might be tricky here we have some polls but in that case you can press Ctrl P you can use the pointy boy and then restart the language server or worse you can restart your development server and the type should be generated typescript is sometimes slow and that's how it is because this is really complicated when you think about it what it does under the hood right so if you ever have problems maybe it's not you first maybe it's time flip so I recommend you check that so we can say each here and then say Li I'm going to have a link here post is going to be slug and this is going to be title since we just structured it so awesome here you can see we have the sidebar everything is good we have our type here all right so now let's show everything else remember we need to use slot here this is going to show our post okay so now we just need some basic styling that's how simple this is how awesome is this right so I can say display grid grid template columns so I'm going to say the sidebar should be 200 pixel not responsive there are 60 characters for the post and I want a gap of 4 REM and then I want to do some spacing to Ram let's save it and awesome this is a great layout so we can see here we have it on the side and now since we created this layout when we load the posting it's going to load in on the side how awesome is this and of course this is not the most responsive thing you can make it more responsive but yeah and I'm also zoomed in so that's why it is but yeah let's just keep it zoomed in for now so let me just give you a summary we created a new layout for the pulse route just so we have some posts here in the sidebar on the left and just so we can load post here this post is coming from this file which is slash post page.12 so we can do whatever here and now when we load a post because we're using this layout where we have this slot here now every post that we pick here is going to get loaded on the right and this is how that works how awesome it is okay let me just zoom in just so we see everything okay hope this is visible but yeah basically that's it but now I also want to have recommended posts here that are going to be the same as they are here and in our sidebar if I go here to routes post we can see here is a child route of post slug page.12 if we go here and hover over data what is this oh here we have the post right and the post itself and here is everything that we need right so we don't really need to create a special file just for this plus page.s cell file where we can already reuse the data we have so let's show the post so you can go here I'm going to create posts give it a H3 post we're going to Loop over it again UL and then I'm going to use the snippet I have so you can say data post s slug title and now inside here we can do the same thing Li we're going to give it a link this is going to be post slug gave its title also now we just need some Styles if you save it it should already work but now let's give it some spacing here so if I go create a style and say posts margin top to Ram awesome and now we reuse this data so now let's try if everything works so this is going to load the post and we're going to get the same recommended post and now when we use this it's also going to change the post but this isn't going to change of course and how awesome and simple was that alright friends before we get started with this next part first let's fix this issue so it'll get canceled so this was in our layout post right so you can just say min max we can say actually Auto and Max 60 characters and they should fix it all right that fix my OCD and I feel already a lot better so let's close this and let's talk about how your data is available everywhere so so far we've seen how data Flows In One Direction but the dollar sign page store makes your data available everywhere so let's see how that works if I press Ctrl P I'm going to go to the root layout which is going to be Source routes and now here I can import the store from cell kit which we already seen in previous Parts how useful this is so I can say import page from Dollar Sign app stores and I'm just going to Output everything here use a store by prefixing with the dollar sign this is just syntactic sugar so you don't have to subscribe and unsubscribe to stores yourself so now I can save this and you can see it's going to Output it for every request so here you're going to have this params and we also have some data so we get post and remember here are the posts from data that we return from our loaders and here is a post so interesting things happen when we go to a post so you get here post and here is a post with the ID you have created it and Etc so why is this useful you might be confused and basically this is really useful instead of repeating something like SEO on every page you can use this page store to use it for your titles and whatever else you need and you can override it for individual Pages if you want so let's see how this can be useful so I'm just going to remove this and I'm just going to create soiled head here and here is where you put whatever you need that goes in the head of the document so we can say title and now remember we get it from the page store and the beautiful thing is that it's also type so you can say data post and let's give it also a question mark because the post might not exist and you're going to see we're going to update the title here when I save so awesome this now updates the title of the post but of course when you go to other parts of your site this is going to be undefined so you can set a default here if you want to you can override this just for those individual pages but now you don't need to do other complicated things to make this work so if you see when I go to any other post it updates the title and this is really an awesome use case for this another real world example I want to show you is when you're using an off library or doing all of yourself you need to somehow authenticate that user so let me just scroll down here so remember how we said that you can return data firmer load function from your your layout that is and is going to be available for your entire app and here is the perfect use case for that so of course this is more involved you're going to first authenticate the user using Hooks and cell kit and then through this event you're going to get the session or the user data whatever it is from event locals so you're going to get the session here and now you can use this from your dollar sign page store anywhere in your app so in this case for off JS it's returning this session and now you can check it in your template so here you have some file whatever and now you have access to the page store and now you can make a check here if page.data sessions remember this is the same session that you return from here okay then you know the user is authenticated and now you can display any data you want from this you can show the user image or whatever else you need and this is really what this is useful for so I'm just chilling here in our API endpoint and I'm thinking to myself how can I make this API more flexible when we first created this API I honestly wouldn't have blamed you if you thought that we just did the same thing that the dummy Json API did but not only do we own this API now we can make it more flexible so let's talk about how we can use the data from the URL first I'm going to remove this limit here and the cache control header since you don't need this anymore and basically if you think about it the URL was the first state manager before any of this fancy JavaScript Frameworks existed a stateful URL means you can use Query parameters from the URL for providing options like filtering and sorting data and circuit makes it easy to work with the URL and that's why the load function has some useful things so we can get the URL from here which is an instance of URL which you can learn more about on mdn and it has properties like origin hostname and path name and also the search params which are going to be really useful in a second you also get the route which has the name of the current directory relative to Source slash routes and you also have params which is derived from url.pathname and route.id and if you go here you can console log it out so you can say URL route params let's open the terminal I'm going to save this let's rerun this so now we can see all these options on the URL here is the route which you can get the ID and your params have other info if you have those but what I want to do is to improve the existing post API so I'm able to specify the amount of posts I want and set the order so I want something like this I want to go to post I want to be able to set a limit and I also want to be able to set an order that's descending or ascending and basically now when we look here we get the search params and we don't really have to do any crazy regex or whatever to get this it's already parse for us we get the limit we get the order and this is all thanks to the web platform again I know you're already tired of eventually in the web platform all right so if you go to mdn you can learn more about this here is the same thing URL search params and you're like okay how do I get anything from this okay has get all okay Etc or you can be a true chat and just use typescript in your project so you can just go here and now since we have access to this we can create a more flexible API so let me just close the terminal I'm going to remove this so we will need params route we're just going to need the URL and now we just need a way to get our limit in order so I'm going to say limit and this is going to be URL Windows URL search params and now we say get what we want to get the limit it's already parse whereas right which is really awesome and now we can set the default if there's no limit just return all the posts and now we can set the order we're going to say we're going to search params again get order or we can set the default here we can set ascending and this is going to return a string but we want a number so we can cast it here to a number you can go to the end and you can just save it like this so in our query here let's just make some space we're going to add some more options Prisma has this order by options and you can select what you want to order it by the ID and of course it already has options since we have great Auto completion it's ascending and descending and of course this is why intentionally designed the API that way because Prisma expects ascending or descending and now instead of using a literal string we can just say order and it's going to complain about some things really somewhat important we also need to specify the limit so we can just say take which is going to be the limit not order so yeah that should work so now if I go here I'm going to save this and right now nothing is happening we also need to refresh so we should get back four posts and it should be in the reverse order which will start from 30. so let's do this and awesome now we get back 30 29 28 27 and the beautiful thing is that the order here doesn't really matter so we can for example remove this we can just say limit or if you don't provide anything it should work the same and now let's just say order so you can say ascending so this will give us all the poles but in reverse order and everything works great so honestly that's it for this session but I actually want to include some bonus which is more food for thought so using the URL for State Management is not a unique concept and something we just started rediscovering because Frameworks like swellkit make working with the URL great again so you use for example to having component States for something like search but you can share the link with someone else so here is an example of this if I told you to make a search like this you would probably do something similar like this but you would use some state in your component like the search query and that's how you would do it but in swellkit and these other Frameworks what you can do is update the search params in the search params when they get updated they can rerun your load function and this can update the data on your page so as you can see here is an example where you don't need any client state or state in your component this is basically just has a form and it's going to trigger the search and then the search get updated the data is going to get updated for the page of course you don't have to understand this everything this is as I said just bonus content and something I honestly think even the swelky dog should include because this is really almost an always but new way of thinking for people so for example if I go here and let's look for Angelo and we get Angelo back and we really had no State let me just also show you how this works in practice I'm going to zoom out because this UI is honestly mind-boggling sometimes so here's what we want I want to open this in the new tab so let's just go to the end I guess I'm going to copy to your analysometer so you can see what's going to happen here okay just click down the exit or someone but let's say let's search for Angelo again and now as we typed if you go back to URL you can see this was updated real time so for example imagine if you're working on a dashboard or something how useful this would be and now if this was a real site which it is of course I can just share this URL with anyone like I can just copy this I close the tab right proof look at that confidence now I can just go here leave I guess it's going to close it but yeah you can see how this works and now we can preserve your state in the URL and I also want to give a shout out to this Library which is okay search params this what I showed you right now looks a bit boilerplated right but here is a Great Library that someone made which makes this really easy so look how simple this is compared to what I show this is even simpler and here you can just import the query param from circuit search params and you can just update the query param like this and there is another great example you can just bind the value and update it easily like this so I think this is something really exciting and something that we just started rediscovering again if you're in the JavaScript landscape because probably everyone else that works in PHP and those other environments are probably laughing at me right now this one is going to be a bit brain twisty we're going to talk about using parent layout data so far you'll learn how data returned from a parent load function becomes available to plus page sweld and plus the layout cell components over the data prop that's great but what if you need the parent layout data inside a child load function in that case you can await the data using parent I want to emphasize this it only works if you return the data from a layout to show this I'm going to go to the deepest route which is our post so I can open the sidebar I can go to Source routes posts Slug and I'm going to open the plus page of server TS file and now here we have access to something interesting we have the parent method so let me just make space I'm going to say cons parent data I have to await it I can say parent and now let's log it out pair in data when I run this code what do you expect to see in the output let me just open the terminal and now I'm going to navigate to a post it already pre-loaded the data so we can see something interesting in return the post and if you guessed that those are the four posts from routes post layout.7ts you would be right because that's the only parent layout load function that returns data so far so we can go to post layout like this and here it is here is a return the data from the load function in the layout so I'm just going to close the terminal another thing you have to keep in mind is that you have to be careful to not introduce a waterfall if your data doesn't depend on the result of the parent because load functions run in parallel if you never heard about this when people say waterfall they usually mean a traffic jam in your network tab so for example if you request something from another old function now that load function has to stop rendering because it has to wait for that parent data to get the data for the current load function and anyways quickly get into what looks like a waterfall in the network tab so I'm just going to close this file and open a new one just so I can show you an example so you can pretend that for example this is um page server TS file and now we export a load function like before so we can say const load which will be page loads for example and now you can say async and now we can destructure the parent so let's do it like that and now let me show you what I mean so first we would want to get the data from the parent first in this case you obviously can't avoid it this is why you're using it because you depend on the data I can say parent data you say await parent and now we have the Second Step because you need the parent data and say data and now you have some function a call to a database or whatever get data now we can paste it the parent data and this is fine if you have to do it but what the silky documentation says is that you shouldn't do this and you should await the parent less so you don't block the rendering so basically what happens here parent foreign function runs first we can even give it a hour less and then you have here this load function is now blocked because it has to wait for the results of the first one so you can just say stop so now we have a better idea how this can stop rendering so here is the ideal that you should do if you don't depend on that data so if you go here so again the first step this load function fires off so you can even give it a nice running Emoji like this we also copy this over so you can just say const data await get data not this get data and then you can say second the parent load function fires off const parent data a weight parent and now you won't run into any blocking issues this is going to fire off then this is going to fire off and now the load functions can run in parallel as long as you keep this in mind you should be fine I hope you're not tired because there's one more thing we have to talk about and that is the secret life of load functions you should understand how load functions work because you're going to need to rerun a load function for the page which circuit already does for you behind the scenes in most cases but in some cases you might want to do it yourself and how this works is that swellkit tracks the dependencies of each load function to avoid having to do the same work during navigation so for example let's take a look at the load function for the slug which shows our post so if we type in Slug we're going to go here the dependency here would be the params so each time params dot slug changes circuit is going to rerun the load function let's look at another example so we can open page the TS in our routes and what is the dependency here the dependency here is the URL inside the fetch so API post a certainly see that the post data hasn't changed it's not going to rerun this function when you navigate to other pages and remember from the start how this goes full circle this is why this special fetch is going to inline the response in the HTML so it's just going to reuse it also a load function that awaits the parent data from another load function will rerun if the parent load function reruns if you need to manually rerun the load function selfie provides you some useful functions like invalidate which you can pass a URL or you can use invalidate all which is going to rerun every load function so be careful with that one so let's look at an example here I'm going to close this and you can also create your own identifier so for example we already mentioned how this is an identifier but you can create your own using the pens so we can use the pens here and you can name this whatever you want you can go here and you can say pens and you can name this banana if you want or whatever but I'm going to call it post or the dog show you this really neat naming convention you can use app or whatever I'm just going to keep it simple and name it post I'm going to save so I'm going to change the API slightly here because I want to show you how this affects refetching the data on the page so what I'm going to do here is return a random number of posts I'm just going to get a random number here we have to say math round and then you have to say math random times 30 because that's the amount of posts and now here in the post I'm going to use backdicks like this and I'm going to say limit because remember we enhanced our API how cool is this and now we can say random so this should return a random number of posts when we revalidate this load function and we can save it nothing changed of course beside the API now we get a random number or post when you refresh the page but we don't want to refresh the page we just want to do it manually ourselves invalidate the load function and rerun the data for the page all right so now we have to go to the page which is going to be here so Source routes page remember here we have our post I'm going to move it here so what I'm now going to do below posts I'm going to create a button and we can say rerun and this is just going to have a function on click you're going to name it rerun load function we're going to create this function right now function rerun load function it's not going to have any parameters so now I'm going to show you all the ways that you can revalidate so the first a method I'm going to call it is going to use the invalidate from cell case so we need to import invalidate from app.navigation and now the first is using as we defined it here that depends this is going to be that let's also Define a b option which is going to be invalidate again and now we can say API post and question this isn't going to work in this case because we created a unique URL so we really can't account for that but in case we have a stable URL it's going to work all right so let's introduce option number c which is going to also use invalidate but we're going to pass it a callback that takes a URL and we can say URL ref if it includes anything relating to post is going to rerun it and let's also include the last option which is going to be invalidate all and if you treat this as a nuclear option so avoid this at all cost if you can but let me just comment all of this out let me just save it so when I press this button now this should invalidate the data on the page and refresh it so let's see if this works awesome and even if you open your network tab let's go to the network tab you're going to see it's going to make a face request you can see it does a random one each time so now let's look at all the others of course this one won't work in this case because we have a unique URL so if I clear this out try it it won't work but it would work if you had a stable URL so let's see the C1 so I'm going to clear it and I'm going to refresh post now I'm going to use the nuclear option invalidate all so you can also rerun it let's repeat what makes a load function rerun if any reference to a property of params or URL changes if the load function calls a weight parent and the parent re-ran if you declared a dependency with fetch or the pens and mark the URL invalid with invalidate URL or if you use the nuclear option invalidate all to force every load function to rerun another thing worth noting is that this doesn't cause the component to be recreated but it just updates the data probe for the page inside your Plus page.selt or plus layout or cell component but if you want to reset the component you can use after navigate or wrap your component in a key Block in the last part we talked about data loading in swell Cable in this part we're going to learn how to work with forms in circuit so let's talk about the project setup first we are going to open the sidebar this is just a regular skeleton circuit project with typescript so you can go to source and really there isn't anything special here I just have a root layout here let me just close the sidebar so I include the Pico CSS someone asked me last time hey can I write Global Styles in the layout and of course you can do it like this you can import whatever you want here globally then you can Define some Styles here I want some padding for the body and I want some rounded corners for the inputs and buttons and this is how you can easily do it in circuit that's basically the setup and nothing special here in the plus page sale file I just have a title here and nothing special and of course I'm running a development server so if I go here I have this default styles using Pico and here just have a title so if you want feel free to catch up alright before we get started I'm going to keep it simple and I'm going to create a fake database and we're also going to learn something neat which is server only modules so remember how we said that if you type dot server TS where a file is going to be only available on the server and same for your data loading this works for any other file so for example here is how I'm going to do it I'm going to go to source and I'm going to create new file I'm going to create the lib folder which as you already learned is the default alias in swellkit and now inside I can create either a file that's going to be called database server TS or I can create a folder which I'm going to do here I'm going to just say server and now I can say database TS which is honestly even calling you generous a fake database because this is just going to be an array of to-do's so let me just press enter and here I'm going to start by defining our type to do so it's going to have an ID which is going to be number it's going to have a text which is going to be a string and completed which is going to be a Boolean so now I'm going to create our fancy database which is just going to be to do's and this is going to use the to-do type which is going to be an array right and the first time I did it I over engineered it completely I use the map or whatever and I was like okay it's time to stop just keep it simple an array is fine for me right and we don't need anything else right so let me just give one default example here so we can see that it works and of course I'm going to give it a date now for the ID because I really don't care and now for the first one we're going to say learn how forms work and then we can say completed false all right so let's just Define a couple of functions and then we're done so we can say export function git to Do's or whatever else you have and we're just going to return the to-do's and really need to do this because really can just export this because it's going to be reference forever so we always have to run some other function is going to return the new updated to do's and then let's keep it simple I'm just going to scroll here we can say export function add to do this is just going to accept the text which is string and we're going to create a to-do which will satisfy this type right so we're going to say ID date now let's just give it a text that we pass to the function and we're going to say completed false and now we just need to update it to do so you can say to Do's push or dear with mutating data oh no okay let's save this and I can now Define a remove to do function you can say export function remove stew it's going to take in an ID which is going to be number and this is going to be really simple we're just going to reassign the value we can say to this filter is going to take in a to-do and we just have to say hey does this to do not match the one we passed in and it is going to filter out the to-do's and the last function I'm going to Define export function clear to-do's so you can clear the to-doos and I'm just going to initialize the to-do's back to an empty array alright so that's it in the next part we're going to start to talk about forms this part is going to be a reintroduction to forms and why do I say a reintroduction because we kind of know how phones work but we really don't from years of using JavaScript Frameworks and avoiding forms like the plague so we used our event handlers on buttons and Etc and we kind of know what happens when we submit the form but how does the form actually work so I'm going to talk about that in this section so let's start first by defining what the form is a form is a way to exchange information between the browser and the server and it's just a container for form controls or also called widgets believe it or not as said on mdn with some optional attributes to configure how the form behaves so let's have a look at that alright so inside the editor I'm going to go to routes and I'm going to open the plus page soil file and I'm going to start by defining a form so we can say form which is interesting so what is this method yeah that's interesting right and now we can define a next and say login and now we can close the form and now we can specify some input fields or as we just learned they're called form controls so we can say input type which is really important just tell the browser what type of input this is you can have a button you can have check boxes and Etc and this is the most important part you have to specify a name because this is used on the server to get the data right and we can also say input type password so the browser now knows this input field is a password and knows to treat it as such and to hide the user input and now we can also give it a name we can say password you don't really have to even finish closing this tag like this because these elements are also called void Elements which means they don't need a closing tag but honestly this is just habit and now for the button we can optionally say type submit which is the default and now you can say login let's just save it and now we should get a beautiful form so here in the form the action attribute defines the location URL where the forms collect the data should be sent and the method attribute defines which HTTP method to send the data with and the form attributes are optional if you exclude for example the action is just going to get or post to itself so first let's see how get works the get method requests a research on the server and appends the form data at the end of the URL so what to expect is going to happen when I type something in so we can say test one two three four and we're redoing a get request so I can say login oh interesting so now it redirected us to the action which is slash login and now we can see it appended the login which is the user query params test and password one two three four so this is great to request a resource or maybe play around with query params but in case of this form this is actually insecure because you're showing the password in the URL right it's also not great for sending a large amount of data over the wire because the body is empty and that's why this gets appended to the end of the URL so let's change this method to post and save it and I'm also going to go back like this and basically the post method is similar to get but it can return a resource depending on the data sent in the request body and no data is going to be appended to the URL and the data is going to be included in the body instead so let's see how this works I'm going to open the network tab so now let's say test one two three four and pay attention to what's going to happen of course we get redirected again and we can see here we get a response so we can see here is the payload user test and the password one two three four and you can also view the source so again instead of being appended to the end of the URL is going to be sent in the body to the server as a list of key value Pairs and this is why the name attribute is so important because if we didn't have the name attribute then it wouldn't know what to assign to these values right and now on the server side we can just say okay give me the form data whatever you have and then we can just plug the values from it I'm going to show you how you can use API endpoints to work with forms and this part is important for understanding how forms work because it's going to give you more appreciation when you learn how simple cell kit makes working in forms in the next section and this is also going to help us understand how that actually works under the hood so next I'm going to create a to-do's folder with some route files so I'm going to go to our editor I'm going to open the sidebar and if you have the swelkit extension you can right click anywhere in your project or use the command palette in vs code and we can say circuit file and you can create a route so you can give it a name we want to name the folder to use and now you can select the files you want so using spacebar I can say page swelt we also want server TS this is going to be the data for the page and we also want the endpoint for the form so I'm going to press enter and now it's going to create it so it's going to create the folder to do so now we have here the page.s cell file we have our data for the pages you're going to fetch in a second and here is our endpoint so let me just close the sidebar and first what I'm going to do is fetch the data for the page which in our case is going to be the to do and you might see this if you're using typescript this satisfy page server load I'm honestly not a huge fan of this because it makes the code harder to read for no actual benefit so we can just remove this and I can just use it like this we can save page server load and that's it it works the same of course satisfy is useful in other areas but in this case it really doesn't do anything alright so because we're using typescript and narratory super smart I can just say const to do's and I will start typing get to Do's aha is going to know that we should import this so you can go here and of course it's aliased and we can just go here so I'm going to say dollar sign you would see what you would have to do if it wasn't Alias so you would have to do all of this nonsense which is really awesome because it's elliot-based default and if it's confused about this you should restart your development server and it's going to work so right now we can just return the to-do's inside of an object let me just save this and we can go here and I love using pre so we can say data and now we should see the to-do's on the page if we go to slash to do's and actually these are going to show the one to do alright so you have the page data and I'm just going to make a to-do so we're going to create two functions we're going to need a function to add that to do which is going to take the event of type event and let's also make another to do I'm going to say function remove to do and simple like that so now we can go inside our template and we can Loop over the to-do's so let's go here and I'm just going to say UL and I have this each snippet and now we can get it to do is we can say data to do's is to do and now we can put it inside An Li and we can use a span so now we can say to do text and now we're just going to use a form and this might be weird to you if you use the JavaScript because you might be thinking okay in the past I just might have used the button here have an event handler so it's really going to feel weird that you're using forms and quotes for these small things but don't be afraid just use forms whenever you can because that's the right way to do it so I can say form and then I can say on submit so we're just going to use JavaScript in this case we can say prevent default which is provided by swell and now we can say remove to do and the method is going to be post so let me just close the form and now I can define a button which is going to be type submit which is optional of course and I'm also going to give it a class delete which we're going to create in a second I'm going to do this and let's give it an emoji so we can say Cross of course you should make this more accessible but a question is for example how are we going to send the ID to the server right so you know what to do to remove it and the answer is quite simple we can just create a hidden input field which is going to send the ID to the server so I can say input type hidden and I can give it a name which we can grab on the server and for the value I can even say to do ID so we can grab the value all right sweet so now we can save it and we should see here is the first to do and we're going to include some Styles in a second to make this better but we also need another form now so this was the form for our to do and to delete them so you can go here let's create another form on submit so you can say prevent default and now we can use the to do function we can say method post let's close the form and this is straightforward we can just say type text I'm going to give it a name to do and then button type submit and we can just say add to do and now let's add some styles oh let me show us to this I can create a style tag so I'm going to say UL padding zero let's just give some styles for the Li you can say justify content space between align items Center and I'm also going to say for the span protection form should be capitalized and we just need to specify the delete and error classes so I can say delete margin 0 . this is just some styling because of pickup so you can say background zero and Border non-actually background is going to be none and border is going to be none also and now for the last error class we're going to be using in a minute we can just say color tomato alright so let's save this and everything should look a lot nicer so you can see here it's still complaining it says okay I have no idea what this is and usually you can restart the development server so you can go here say pin PM run Dev and this should resolve it and now it's going to generate whatever it needs and you can see it's happy now and as we learned previously you can see how we didn't specify the action attribute for the phones because we're going to submit it to the same page so now inside the server TS file we're going to create the post and delete functions so let me just scroll up here and we already have the data here so we really don't need this I can just close this I can go here so let me just remove this response and the first thing I'm going to do is actually declare a type data and this is just going to be responsible for returning success and errors for the page so this can be whatever you want this is just the shape I decided on so we can and do things based on what is returned from this so this is going to have a property success which is a Boolean and it's going to have an object of errors and how we type errors in typescript you can use record and then we say hey the key is a string and then we can also maybe say unknown for the value but we can also give it string and this really isn't important and now instead of using get because this is going to be a post submit we're also going to use post and we need a request so we can get the form data right so you can go here and now we can say const from data so we can get the form data await request and types we can help us also you can say request okay what is here form data nice and then you can get it to do so we can say form data get to do and this is the name of the field on the form right and now we need to make sure that this is a string because if you hover over this is going to be form data entry value typescript really doesn't like this so you can just say string and that's it so now I'm going to create the data object I can say const data actually let's give it the type data this is why we created it so I can say by default false and we can say errors which is going to be empty and now we can say if there is no to do we can say data errors to do and we can say required which really isn't important and then we should probably throw this and catch it on the fronted but really this isn't important so we can just return Json we can use the helper from cell kit let's say Json data and we can also give it a status which is going to be 400. and now if everything works I'm just going to go here and I'm going to say add to do this is going to Auto Import it from our file so you can see here it works everything nicely in the background so let me just sort these things awesome so we can say add to do and we can just pass it the text right and then we can say data success true and we can also return the Json with the data let's do it like this I can save it and now this is the pose done and the delete is also going to be simple so you can go export const you want to use delete going to be the same type request Handler async we're going to the structure request let's say again form data again we're going to get the form everybody thinking yourself this is tedious and you can just subtract this inside the function or whatever so you can say form data and now we can say cons to do ID and we can say form data get and we call it ID right so if I go here let me just see yeah we gave it the name ID and this is going to give us the to-do ID so we can go back here we need to cast it to a number because it's going to be a string so we can do it like this and then we can just import remove to do so again it's going to import it because typescript is smart like that and now we can say remove to do we can pass it the to-do ID and that's it and let's return some Json and we can even say success true and we can save this and that's basically it so now on our front end we can fill in the function so if I go here here is the attitude so let's fill that in but first we're going to need the same type so I can even scroll up here let's just copy paste it you can already see how this is starting to be tedious now we need to copy over that part data right and I also need to keep track of whatever we're going to return so I can create this variable this is going to hold data right and now we can fill in the add to do so we can say const form element event Target we need to say s HTML form element so typescript is happy and then we can say data new form data and we can pass in the form element and I'm also going to console log it out like this and we're going to see that in a second but first i'm going to Ping the endpoint so I can say cons response and I have to say await fetch what we want to Ping we actually don't need to specify here because we have a reference to the form element so we can say form element action how awesome is that and now we can give it some options we can say method post and we can pass the data so now before I continue let me just show you how that works so I can open the developer tools let me go to the console and now we can submit it or whatever and we can see the form element is here and now we have everything which has to do with that form so we got the action you can also get the method but this can only be a post like this so we type post and you can also see the data so instead of the form let's log out data so now if I type whatever you can see form data and let me see if I say log and we can see the form data object and all the properties available on it so you can get the value and Etc but I'm just going to remove this and let's just continue so now that we get the response we will need to populate this form right this is why we did this data thing here so now we can for example say cons response data and now we can just await the Json that we return so let me just console log it out so you can see what's going on response data I'm going to clear this so let's not submit anything we can see success false and now we get back the errors which is required so you can use this in our template but let's see what happens if we submit something so we can say test and now success is true and errors should be empty so now basically what we need to say we need to set the form variable we can say form is equal to the response data another thing you can see is that this persists when you submit the form and how do you reset the form well you have access to the form right the simple is saying form element reset as you can see you get great Auto completion so now if I type test and submit it it should disappear there's one more thing we have to do so you can see how nothing updated on the page let me see if I refresh the page you should see ah here the to-do's that we typed in okay so how can we fix this let me just close this so we have space to work with and you can see here are the to do's and basically this is happening because we have to invalidate the page data and we have to rerun the load function so in the data loading part we learned that we can use invalidate which we can use right here so you can say up late invalidate let's just use the nuclear option we can say invalidate all I'm just going to save this and now if you see if I type in test and add it it should update immediately and also it works so you can see let me just say banana you can see it added banana alright so sweet this wasn't that bad right so let's do the one for removing the to-do and also I can just remove this placeholder and let's do it and now again I can say cons form element Target is HTML form element I can say cones data new form data so we just passed in the form and now again we can just say const response we can say await fetch use form element action and let's pass it some options so an interesting thing is that a form can only do a post and get so even if you do a delete it's going to do a post to the server and that's basically to the way the HTTP standard is made and that's really a story for yourself where basically selki is going to know what to do because we created a function delete so if we say here method delete this should work without the problem and now we can also pass it the form we can say body data and remember we have to invalidate the data so you can say a weight invalidate all which is already imported here at the top for us all right so now that's basically it so we can just save this and only see if it works so let me just start deleting things okay awesome you can see how this works all right but for example how do we show the feedback to the user so right now there's nothing right but remember we returned this data thing so it has a success and errors and this also gets updated right so now we can use this in the template so here it is with the to do so let me just make space I can just say if and now we can say form and because the next value might not exist we can use this Nifty trick we can say errors and because the to do might not exist we can also use a question mark and now we can create the P tag which is going to have that class of error that we made and now we can say this field is required or whatever else you want and let's also do one for the success so here we can say if and now we can say form if there's success we can also give it a paragraph added to do and let's give it some Emoji we can say party so right now if I submit the form the user should see the feedback which is me so the field is required awesome so now let's set something we can say banana edit edit to do and how awesome is this then you can of course see everything in the network tab so let's see how this works if I go here and submit nothing you should see 400 to do is empty and if we submit something else we should see new to-do's which is going to be test and you can see in the preview and the response is the data which returns so this is the raw response and here you can see errors success and for the other one that failed we can go here you get the errors back and yeah that's basically it so this was basically just an exercise so I can show you that it really doesn't matter what your return it's basically up to you how you want to handle the error validation which leads us to the next part so this taught us a lot about forms and endpoints but this is not a great user in developer experience and why is that because for example this only works with JavaScript so you can see here for example how we had to prevent the default form Behavior now we had to go here even if we have a server right here we had to implement all of this ourselves we had to use fetch which is really tedious so imagine how it would look like with a more complicated form we we had to invent around wonky validation like this thing is not ideal I wouldn't use this right we also had to use Fetch and invalidate all which is the nuclear option right and really the framework should do more for you and this is why you should use swelkit form actions in the next section I'm going to show you why they're so awesome so finally let's talk about swellkit form actions so remember how inside a standalone plus the server TS endpoint you can use functions that map to http verbs like get post and delete like we've done it here so you can see delete post and whatever else you want but form actions take this idea a step further and you can Define methods that map to an action inside a plus page or server TS file so you can go here and you can export an actions object which is going to map to the actions in your form I'm going to convert the previous example to use form actions first I'm going to delete this endpoint file because we're not going to need it anymore so I can close it and I can go to the sidebar and let me just press delete and we can move it to trash because we don't need it and now inside of here we can Define the form actions nothing else changes about this file you still use it to fetch the data for the page but now you can also Define form actions so let's start with creating actions for adding removing and clearing the to-do items so this is how you do it you can say export const actions and it uses the type actions which is going to be imported for you so let's put it at the top and now you can give it an object so this is going to use default if you don't have any actions on your form like this but if you define a name action which you're going to use then you can't use default anymore so now let's just Define the actions we have and this is really simple and awesome because also remember when we use post right so if I go here and where is it in our template let me just go here so for example here it was for adding a to do but now what if you want to clear the to-do's or do something else or have three four actions or have different forms now this starts to get hairy because every method is going to be post so now you probably need to include some query params or have some hidden Fields so you know on the server what you should do based on what it gets right and this is really tedious and annoying and form actions are amazing because of this so let's just Define our form actions so we're going to have one that's going to be add to do we can say async and also remember this takes in an event object like we've seen everywhere you have something with data loading you're going to have this object we already learned about it so you can have cookies fetch locals params or whatever else here you're going to take in our request from here and let's also add remove to do so we're going to say remove this is also going to be async and it's going to take the request we can also say form data await request it has phone data on it and now we can say cons to do and now we can use form data we can say get to do let's turn this into a string and now we're going to do some error validation which is going to be way easier than what we did before so now we're going to say if there is no to do swelkit has a handy fail function that we can return a status and whatever else we want so you can say return import fail which is going to import the function if we go here so here it is fail and now let's see the argument so we can give it a status we can say 400 and now again this is up to you you can return whatever you want so in our case let's actually return the value so we can use it in case the form gets reset then we can just repopulate it so we can return the same value we can say to do and now we can say missing true or whatever and this is going to be available on the same form prop that we've seen but now it's official by swelkit alright so that handles the error case and let's just import and to do and same as before we pass it to do and now we can just return success true and basically let me save this and now let's also fill in the remove to do again we can say form data request form data let's say cons to do ID and let's just say number because you already know and we can actually let's just get the ID sometimes typescript is overzealous and this is because we need to also include a weight request all right so now it's going to be seek how typescript saves your bacon I would notice this and I would waste minutes of my life all right sweet so now let me just scroll up here and now I can say remove to do again I'm going to press enter this is going to import it let's just pass to do ID everything should work great and we can return success all right let me save this and this is it basically you can already see how much less code this is alright so now let's update our template so if I go here and now I can remove all of this nonsense I can remove these functions let me remove this I'm going to remove this type of deleting code feels better than writing code to be honest we don't need invalidate or a sweet so now we have export late data this won't change at all ah now we have another thing from cell kit export let form which is going to be of the type action data and let me just instead of data we're going to save form and right now there's nothing but we're going to see how we can update our template so now we want to use JavaScript here so we can remove on submit for the poster dishes you are going to stay post and now we can Define the action right so how do we do it and this might look like magic first okay so check this out so we say action question mark and we can say remove to do but that wouldn't work right because this is a query param and circuit won't know that this is an action or you're trying to invoke connection so how do you do it in swelkit well you just add a slash here and now swellkit knows that you want to call this function all right awesome so now let's update the other form how good does this feel right so we can delete this code and now we can say action what was it question mark slash add to do and now we can update this so we return form missing and now we can keep this as this field is required and also let me show you something else what is cool so we want to clear the videos right so if I add this button we can say clear okay but how do we do it so let me first add a class which is going to be secondary and this is of course optional but I like having it let me just save it so you can see here we have cleared okay but how can we invoke other functions right because we specified here that this form should invoke add to do well simple this isn't a circuit API or anything this is using web standards so on the button you can use this property form action if specify it overrides the action attribute of the buttons form owner okay so this is going to override it awesome so let's see form action and now we can again say question mark slash clear to-do's and save it how awesome is this and here nothing changed we again return success so this should work one downside though is that this type generation is sometimes wonky like here for example here you can see its form missing but you're going to see that this should work so when I go here let's first see the error handling so I can say attitude this field is required also notice how our browser refresh because we're not using JavaScript and this is why your app is going to be more resilient because it's going to work before JavaScript so you can see how we get back the to-do and missing so basically the editor doesn't know about this but what you can do you can press Ctrl P type the pointy boy you can say restart Lancaster and sometimes that's going to do it sometimes you need to restart the development server and really if continuous erroring like this just ignore you because you can see everything works just fine alright so let's see we can say test we can submit it oh how awesome it is or let's see if we can delete it ah awesome so now let's add it back again let's add more things and now let's see if clear is going to work right ah awesome how beautiful is this so let's also look at the network type right let's see what's going on I'm always curious about that you know me so for example if we just had a banana so you can see all this junk here and we can see how this is parsed so in the headers it did Slash deduce you can see this is a query Prime but because it uses a slash silky knows it should invoke this function here you can see the payload here so it Powers the query string here and you also get the form data which is really awesome so you can see the preview and the response here which is going to be the HTML document of course so let's try removing this and it should also update of course it has a complete refresh you can see here is the ID and the parse query string parameters and again actions might look like magic but they're just a URL that invokes a function as you've seen swelkin makes it special by including a slash that lets zelkid know hey I should execute this map as you can see how this is really an awesome mental model you can have as many actions as you want and forms and Etc you can just go here to your actions object you can just add a new one let's talk about Progressive form enhancement so we've seen how already this is really awesome so we can add our to-do's or whatever else but the page refresh is really not a big deal but what if you want to preserve that awesome single page application experience and this is what Progressive form enhancement is for let's pretend that in this case the user doesn't have JavaScript because it can fail for whatever reason right your form is still going to work and Etc but if the JavaScript is available on the page we can enhance the user experience so we can do client-side validation or whatever else you want and let's see how simple this is to do and remember the point is not that your site should work without JavaScript but before it because JavaScript can fail and this is what makes your app more resilient so remember in the first example how we had to do everything by hand well basically swelkit does it for you and wraps everything in a pretty bow in a neat use enhanced sweld action this is unrelated to form action this is swelled actions which let you hook into life cycle methods of elements so how do we do this this might sound like super complicated but believe me it's one line of code if you count the input all right so how do we make this work we can go here to the form and now we can start using a swelt action we can say use enhance and as you start typing in hands you can import it so you can see here at the top it imported enhanced from App forms ah awesome so now let me just copy this over that's it that's all trust me so now we can go here to the other phone we can say use enhance ah interesting so what happens now you can see now if you look here the page isn't going to refresh oh awesome how awesome is this to say test or whatever and now we can also remove the videos and notice now we get that awesome experience but let's see what's going on in the network tab right so let me just do delete like this and now instead of refreshing the page right it's going to use JavaScript script and client signed rendering because the JavaScript is available on the page so you can see our fetch request and here it is you can see preview it Returns the data status and the type which you're going to look into here is the raw response and let me just close this so when you submit the form using the use enhance action is going to update the form so right here is going to update this it's going to update the dollar sign page dot form store and it's going to update the dollar sign page.status property it's also going to reset the form and rerun the load function for the page so you don't have to use invalidate all yourself and in a case of a redirect is going to use go to so you can see if we go here and add whatever is going to work just great and also the error handling so you can see here it updates live and this is why I wanted to show you previously how you can work with forms using an API endpoint so you can understand actually what swelki does under the hood otherwise you will just use this and treat it as black magic which I honestly don't like I love magic but I also love understanding how things work and let's look at the implementation which really isn't spooky I honestly maybe don't understand half of this but if you can at least understand the general idea of what is doing and this is going to look really familiar okay so when I look at something like this I'm like okay junk junk I really don't care about this series oh here it is here is the magic sauce here is the salt actions I already know about cell to actions right so I can see okay export enhance it accepts a form right and a submit value and we can already start seeing some familiar things here we can ignore this here it has a handle submit so it really does the equivalent what we've done before it prevents the default behavior of the form here it specifies an action then it does again that things with the form data right how familiar is this right you really don't need to understand these things but get a high level concept of how it understands this is going to give you more confidence in working with these things right and here is the abort controller so you can prevent requests and Etc and really here is the response so it's trying a response ah this looks really familiar right look a weight fetch action method post here is some special sauce headers are actually not important you can see some other things which you can dive into and basically that's it and here is a cleanup if you know what swell actions are all right friends how cool is this but now I want to show you how you can customize the enhanced action and we're going to use it to show a loading UI so how can we customize the behavior of the user enhanced action and you can do it by providing a submit function that runs before the form is submitted so here you can do your validation or whatever and then you can also return a callback that has access to the result so let's see how this looks like so here for example where I have a to do we won't edit for the removing of this you do so we can just go here and wear it using hands is now we can specify a function so you can just say add to do you can name this whatever you want whatever flows your boat like banana right so we can go here and now we can define a function and I'm going to do it using an arrow function because I want to use the type which wouldn't be possible using a regular function I'm going to say const I had to do and this is of type submit function so this should import it from App forms all right so now here we have the first argument which is going to be the input and now let me just put it like this and now inside of here you can do something before the form submits so now maybe you can here do validation of the inputs or whatever because we're going to see what you have access to here and this is maybe you don't really want to submit the form to the server right for no reason if you can already validate the data for example let me say that I'm typing my name here and it's really a frustrating user experience if you find out your name is taken once you submit the form I want to know immediately if my name is taken you know what I'm talking about how many annoying sides do this right so this is something you can do here and then you can provide a return function so you can say return async and this has options so you can do it like this and this is do something after the form submits and you can see because we're using our custom callback functions the form isn't going to work using the user enhance method that we're going to see how to make that work again so let's just see what do we get so we can say console log input and now we can also go here options let me save this and I'm going to open the developer tools let's just go to the console and now let's just type something in ah so this is really interesting so for the input we get this object we get an action which is a URL you can get a Cancel message you can cancel the request this is the abort controller which you can also use for canceling request uh here is the form data itself right how awesome and you have access also to the form element and here is very similar for options it has an action it has the form data the form itself but it also has a result which we're going to learn about in the next section and how awesome is that and here we have something which we can use so we can do whatever we want here and we can call this update and this update function is basically going to run the logic it will do otherwise if you didn't specify a custom callback otherwise you would have to re-implement all that fetch nonsense yourself and Etc but swelkit really makes this easy so let's look at the real use case for this you can't always rely on a fast response from the server in which case the user might leave your site because it looks completely broken so what I'm going to do next let me just close this I'm going to go inside page server TS and I'm going to Define our sleep function which is going to simulate a slow response so right after the load function we can Define it here and we can say async function sleep is going to take in milliseconds and then we can just say return you promise like this we can use resolve and we can say set timeout and we can just resolve it in whatever time we pass in so I can save this and now that we have this nice helper you can put this in your utils or whatever let's just go here and before we add it to do we're going to simulate a slow Network you can also do it from your developer tools or whatever but I can just say await sleep and we can say two seconds so now if I go here and add a beautiful banana you should see oh there's no feedback and the user is already starting to be frustrated they're like okay what is happening and in this case nothing is happening because we lost the default Behavior so if I go here let me just the structure update and now we can say away update and we can also remove this output because we don't usually need it here just remove this I'm going to save it so now again let's try adding something again nothing is happening it's going to take two seconds and ah you see and we already submitted the old one so now you get two bananas which is awesome two bananas is better than one okay so how can we give the user something useful right so let's first Define some state in our components so you can say let loading false all right so now you know that here you can do something before the form should miss and here you can do something after it's done so do you already know the solution so of course we can go here we can just say loading automatically to true and let me just bump this up so we can say loading false when it's done right you can say false and it's going to update and now also let me update the template so if I go to adding R to do Pico has this awesome thing which is Aria busy so if Arya busy is true is going to show a loading spinner which is really awesome so you can say Aria busy and we already have a Boolean right here's the loading how awesome is this and we can also give it a conditional class we can do it like this class secondary what is the Boolean loading let me just say this how awesome is this friends so now if you go here and I can say one two three four whatever now this should show a loading spinner here because it's going to take two seconds or let's see oh how awesome and we can also even make this better so here where the text is let me just like this and now we can just do if it's not loading show the text so you can just say add to do let me just save this and we can put this on one line but who really cares okay so now let's go here and we can start adding something all right so now it's going to take two seconds and awesome and you can also disable the input or whatever you want all right so how awesome is this so now for example if you get an error or success State you can show a toast notification to the user which is really awesome but I'm going to leave that to you as an exercise alright friends let's learn how we can do form validation in circuit and first I'm going to show you the hard way and then I'm going to show you how you can use a popular schema validation Library like zot and show you a couple of Tricks along the way and I'm going to create a login route using this first example so this is from plus page.soil you can just copy over this form and now we're going to close it and let's go to the routes we can say spell kit files create route we're going to create a login route we're going to need pluspage.17 and you're going to need plus page server Ts for order form actions so let's press enter and now you should have a login folder so here is our page and here is our endpoint so we can just remove everything here we're not going to need it and here let me just copy this form over so really don't need to specify an action here because it's going to point to itself which is already slash login but I'm going to import using hands like this which is awesome and I can even specify they should use typescript all right so let's save it alright so let me go to that route we can say slash login and now if I submit it nothing is going to happen right so we can say required which is natively supported in the browser so now if I try to submit it's going to say hey please fill out this field but there's a problem with this any hacker man can come along and they can inspect this and they can say Okay required not today type password I really feel like you should submit an email today and this is going to cause chaos okay and this is why you should always do server side validation alright so I'm going to close this and I'm going to remove required for now because it's going to get in the way and now I can go to the page dot server TS file and we can say export cons actions it has the type actions which should be imported so we can use the default method and we can adjust the structure request like this and awesome all right so let's get started first we need to get the form data of course const form data you can say await request form data and now we need to get the input values so we can say user we can say form data get user and then I can just copy this over and you can say password and of course we need to turn this into a string you can already see how this is starting to feel tedious because imagine if you had something more complicated and yeah I'm just painting a picture here so all right so here is something else we need to do now we need to invent our own way again how to handle errors you can do this many ways but I'm just going to have an errors object any of the error object has anything in it we're just going to return the errors so I can say const errors going to be an object let's just give it a type like this so remember record and we can say the key should be a string and unknown and this really isn't important so this should be empty and now let's do the validation right so let me just make space here so it's readable and now again now you have to do your own validation and you might not be even thinking about these things so for example you might be thinking okay if the user doesn't exist maybe that's it but you also need to check that they're not screwing with you so you have to say type of user so if this is a string right and then if this fails we can say errors user required but really doesn't matter what you say here okay so now we have to do the same thing for the password so now you have to say password or type of password is it equal string and I'm already falling asleep I don't know about you and now we can say errors password required and all right this is how everything is going to work so now we can say if so now we need to get the length we can say object keys and we can pass errors and now we can say hey is there any errors here and then we can do something and also here I can just fix this it's not the three s's so you can use this like this awesome that is resolve and now we can do this validation so now we can return fail so if I press enter it's going to import it let's see at the top all right that worked fine and now we can give it a status and we're going to return some data and let's just make this more readable so I'm going to Define it like this I can say cons data okay so the first thing I want to return is some data right and then I'm also going to return the errors all right but how do I return this data and basically I just want to turn the form data into some object we can get so we can say object from entries we can pass it form data and this is going to return an object instead of form data and we can just return the errors and that's basically it it really doesn't look complicated but again it's really tedious right and for the last part we can say if everything was successful let's learn about a new thing okay so how can we redirect okay swelkit also has a useful method for this so we can throw a redirect you can Auto Import it so it's going to import redirect okay now awesome let's see what are the options you can specify a status let's say 303 and where we want to redirect well let's pretend the user is logged in and now they can go to the to-do's alright so now we really didn't use the validation in the template but let's say if we type this one two three four it should redirect to deduce all right awesome all right so now we can go to the template and again we need the form data so we can say export plate form which is going to be action data let me just do my snippet here so you can see what's going on all right so this is really cool so for example if we don't specify anything we're going to get this shape so you're going to get data user password empty and the errors right which is really awesome and then let's say if we specify the username or whatever you can see here is the user so now because the form resets we can use this value here so let me just show you and let me just go here I'm just going to make space here we can go to the user and now here we can say value and now we can say form data if user is on here we can use that value otherwise we can say hey just leave it empty and then let's do some validation we can say form errors user let's also not forget the question mark and we can also give it a paragraph let's see paragraph class error and now we can say name is required all right so let's copy this over we're going to do the same for password you can already see this is easy so we can say password and you can say password is required all right so let's save everything and let's specify some style so you can say Style error color tomato so now we can see here password is required let me just remove this so you can see we get both name is required so if we input our password name is required but if you do this everything should work great and you should redirect us awesome let me just refresh for good measure and now you can see what's going on again here password required and that's how we can output this in the template all right this is really cool but again as I said this is really tedious imagine if you had something more complicated now you have to do all of these if statements you need to get the data from the form and this is the result comes in and so it is basically going to validate the schema which you can set up yourself so we don't really need to do this if or whatever and the template is actually going to stay the same which is really awesome so I'm going to open the terminal let's stop the development server and now I can say pnpmi zot and I'm going to use another package which is Zod form data which is really awesome because you can just pass the form data or URL search params which you can parse and it can validate that so let me just do that quickly and another awesome thing about zotform data is a great example of using web standards because that package was made for remix but because remix and swelkit use the web platform it works flawlessly all right so let's start the development server again let's close this so now let's change this example to use salt for validation and I'm just going to remove everything here just so we can see how that works all right so let's make some space and now again we just need the form data so we can say I'll wait request form data so now we can Define the schema and how do you do that and we can say login schema and we're going to use sort form data so you can say zfd and this should be Auto imported awesome and then we can say form data and now you can Define your schema instead of doing all those if conditionals right and what are the fields we can say user so we can say zfd type of text or you can even use Zod which also has validation method and we also have password on it which should be zfd text and this is really awesome all right so we need to parse it so we can say const result and you can say login schema and on the login schema we can invoke save parse and we're going to pass it the form data and this is why this library is awesome so let me just scroll up and I'm just going to put it like this and now we need to check if there was an error so you can do it by saying hey if the result wasn't a success and now we can do the same thing that we did before so I can say return fail we can give it 400 and we can return the data now you can see what is going on so you can say data and this is awesome all right so how do we return back the data I can just say object from entries and let's pass form data back in and now for the errors which is more interesting you can learn more about this by reading the Zod documentation from the result you get error and we can flatten it and now we can also return the field errors so let's return the field errors and lastly let's also do a redirect so you can say Throw redirect if everything is fine 303 slash deduce all right let's save everything and you can see already how this is so much nicer and easier and now you can store the schemas in a separate file you can abstract this validation logic in another file and you can pass it form data in the schema and you can return back the data in errors if you want and make it reusable and as I said before you shouldn't have to change anything here and now when you go here let's see if this works you can see data user password and the errors and of course I don't know how to type because you can see here we use the two hours and here let me just see errors yeah left we can adjust it and let's see okay now name is required password is required so I can say test awesome so now if we just do this and let's submit okay so now let's do both and this should redirect us to reduce awesome how awesome is this right of course this isn't the only way to do validation result and you can read more about error handling in this alternate documentation but form validation honestly deserves its own video alright friends in the last part I want to show you some Advanced enhanced action customization for example I mentioned how actions can be invoked from other pages in this example I want to reuse this login form so just want to copy it over let me just close it and here in the page 12 which is our home page or root we can just replace it and let me just save it so now if you go here and you will maybe expect that this would work and if we go here of course it wouldn't it's undefined because the form didn't get updated because it has no idea even if we let me just we have to say action it should go to login right because we're inside our root and we're going to basically Target the slash login so now we go here again nothing is happening the redirect should only work so now if we type anything here it should redirect you to Do's but how do you make this work and we can make this work customizing the use enhance action so for example I can go here and let me just say login and now we can go here and I can say cons login which is type submit function so it's going to get Auto imported for us and let's just do this and now we can return the Callback which is going to be async so previously we learned about update right it might be thinking okay maybe if I try update but you're going to see this isn't going to work right because this isn't going to update the form data for other routes but only for itself alright so here is something awesome we can do besides update you get this awesome result so let me just console log out result and let's open the developer tools and now when we submit it you can see we return from the action type failure status and even the data with the data and errors and how awesome is this so you can see right now it's not even going to redirect because again we provided a custom callback so now when I say test1234 it should be a redirect so you can see redirect status and the type how awesome is this so now you can use the apply action method which unlike update can update this form property and the store for the form from anywhere so you can first get the result like we did it now but now let me just say await and we can import apply action so it even tells you what it does the auction updates the form property of the current page with the given data and updates the store and in case of an error is going to redirect to the nearest error page you're going to see how this works in a second you can say apply action and now you can pass this result right so look at this so now when we let me just close this so now when we Press login it's going to return the data which can be reused anywhere how awesome is it so now name is required and now if you say test1234 now we should redirect to deduce and how awesome is this because now you can reuse this anywhere and you don't have to again specify the same actions and return the same data all right but let's have a closer look at apply action so let's just cancel out the result which we already did but what does apply actions really do and really it depends on the result DOT type so if we go here let me just remove this so we can make space let's say result type and now we have everything here from success to whatever else we have error failure redirect so let's say for example that we only want to do something when it's a success otherwise it won't do anything we can just go here then you can do whatever you feel like doing here and then you can say await apply action and you can pass it back the result and this is only going to do what this logic does in the case the result type is a success and nothing else so for example in this case this is only going to redirect us on success or if there's a redirect so for example it changes to redirect but this really isn't going to return data for validation Etc so if I press login here we shouldn't get validation back because this is only going to apply the logic related to this type of result type so if you press login you can see it doesn't work but it's only going to do this if the type is redirect so now it gets back to redirect and that's all that works and this might be really confusing at first the difference between update and apply action but just so aware of it and when you run into that situation where you really then you can be like okay maybe I should go back and re-watch this or I should read a documentation So based on the result type if you get success and a failure is going to update the form the dollar sign page result form and dollar sign page.status regardless where you submitted form this is the difference between apply action and update and if it catches a redirect is going to invoke go to and use result.location and if it gets an error is going to render the nearest plus error.swell page this way you can customize the behavior of the using hands action and dip in and out of the regular behavior when you need it in this part of the swell kit series we're going to learn about using Advanced layouts in swellkit and why they're so useful so if you want to get started I have this project here I set up in advance so in the post if you want to follow along the easiest way is to open the project on stack blitz so you can see it's easy as opening a link which is really awesome or if you prefer your local development I have instructions in the post so you can clone the project install the dependencies and run it and then you're going to have this development environment here okay so let me just close this and let's continue alright friends before we get started let's first talk about the problem I'm working on this million dollar idea which is plume a site for discovering and sharing inspiring quotes don't ask about the business model first we need to focus on growth and then we can talk about it in 10 years and also by the way hot tip if you need to come up with a cool sounding name just use a word and translate to one of those cool Latin languages like French Italian or whatever else or you can spice it up with some German or Japanese alright friends so what is the problem before I can ship the arc to see I need to ship this code to production but I have some problems here let me turn on some hacks so I'm going to go to my developer tools here let me just enable layout so we can visualize how these layouts work and really this project isn't really anything complicated I'm just running a basic soil kit development server so here in Source we have routes and here we have admin and quotes and really nothing special so here are the ID and text and if you look at here here is the root layout and then we have quotes so now we can see here is the nested layout because quotes in here is the root layout as we learned previously in layouts so now this all works as expected but what is the problem here for example I have this admin folder here and really want to use a separate layout for that so for example investors are tech savvy and I'm going to look like a clown because if you go to the dashboard which is the admin section always shares the root layout and the admin layout when I want a separate layout for this so that's not a great look right and also another problem I have let's say we go to quotes this looks all great right so we can go by tags or go to the quote itself so let's see we can go here and that really looks great so you can see how we share the same layout for quotes ID and all the children this is exactly what I want I just want to show more quotes in all of the child Less on using this codes layout but here's the problem if I for example go to the tags now because tags shares the same layout AS Slash quotes lives under slash quotes right is going to inherit the quotes layout when I just want to show the text and the root layout so I want to keep the navigation right this is another problem that you're going to need to solve to solve this problem we can use group layouts alright so other group layouts group layouts basically let you group related routes inside a directory which is wrapped in parentheses but they don't create a new route so if you remember this embarrassing admin section really want to create a separate admin layout for this and let's say that the plume site all of this code stack which is user facing we can say that this is going to be an app layout so again everything here that's user facing is going to be the app layout and then let's say pretend when we log in into admin introduce a separate admin layout alright so let's see how this works I'm going to open the sidebar I'm going to go to routes and I'm going to start creating some folders which you can name whatever but I'm going to name it app and I'm going to name it dashboard and now it's easy as dragging folders around so just ask yourself the question all right so what belongs in these folders and the admin one is going to be the simplest it already has a layout here which is going to apply to the children and let's just drag it into dashboard let's say move and you might have this prompt to update Imports but just say no unless you have to of course and that's basically it for the dashboard section so okay let's look at the rest of our application we have quotes Okay let's just move this into app because it's where it belongs right but this really isn't going to work yet because we need to update or in fact we need to add the layout to the app because right now we're using the root layout so if we open the root layout I'm just going to select everything and copy it over and here I'm going to just leave what's necessary like the global Styles and Etc so let's see what we need here anymore we don't need this navigation anymore because we're going to Define that in the app layout right and I'm also going to remove the Styles here let's leave this although don't forget to use slot and now I don't need this anymore and I can leave everything else and awesome that looks great right let's just go to here inside the wrap and let's go new file plus layout so else we can create a new layout for the app layout right our admin layout is now working beautifully which is great and now we can remove things that we don't need here so I don't need this we want the navigation of course I don't need my devtools anymore here we open the global Styles in app and we can just remove this import let's just save and now when we navigate you would expect it to work right but there's going to be one problem so let's first navigate to our site and all right okay what is going on like this is confusing where is the navigation right and basically if you remember let me just close this layout and I'm going to collapse everything just so we know where we are if you remember in rails we have this route layout here and this home page is right here right but it doesn't have anything in this root layout anymore it doesn't have the navigation Etc so if I close this if you want this page to be the root of one of your group layouts you can just drag it in the group layout so I'm just going to take this plus page of cell file and I'm going to drag it into app and that's simple as that okay so let's move it and now everything works let me just close everything and how awesome is this so we can go to quotes everything works just like before and now we're going to go to the dashboard ah great okay so let's go back so next let's fix the tags layout if you remember the problem I had if we go let me turn on my hacks and also let's recap so here we have root and let me just rename if I go here to routes app because this should be named App instead of root awesome let me just close this so as you can see here is the app layout when you go to Chrome same as before call slide but remember we're going to go to a quote this is great but if I go to tags I just want to show the tags and how to use this quote layout right so I don't want other quotes and Etc so how can we fix this if I go here and I'm just going to collapse it just so we know where we are because it's really confusing having to navigate to load these things it's in a cider app quotes and now we already explained what this problem is so we can create two separate group layouts in quotes which is going to be one for the ID and the tags so I'm going to do this by creating a new folder and I'm going to name this quote and I'm going to name the other one tags and that's it so same as before we just need to start dragging things around all right so we have the ID where does that go that's related to the quote right so we can just move this inside quote let's say no and the text go to the tags group layout awesome and when we refresh it's not done yet because we need to move this plus layout server TS and plus layout sweld because this is related to the text right so this is going to show more quotes and we just need to move it to its corresponding group level it's going to be quote so let's just select those two and we can move it to quote and let me just close this is going to error for a second and if you refresh ah it works right and now for example we're going to see a problem when you go to quotes we're going to see nothing because again remember here it is this plus page.s cell file which we need to move into quote right so if we see it here here is this cover and share inspiring quotes actually this is the starting one as I already told you this like gets confusing really fast so this here is their plus page I really wish in vs code it would be so much easier to parse this folder structure it would give you line spacing or whatever but that's beside this point so as you can see here it is here is very big it's a random quote and whatever and we just need to move this file inside our code so let's just move it here and everything should work great even though it says error don't trust it okay so now we can see let me just close everything here don't save just close everything here and let me turn on the hex okay so now when we go see here is our home page so now we're going to quotes everything works great we can go and share it if you want so let's see if you go to text oh how awesome is this so this really isn't going to inherit that layout and this is really awesome and now even if you go to quotes and again let's find this code and if you go to the inspirational one we're not going to see more quotes here and now we change the layout successfully so as you already seen group layouts aren't that bad but I think what makes them confusing or difficult is when you start nesting layouts like this because you can think of group layouts as a bucket to put things into but if you're not confident in using layouts yeah this is going to be hard to wrap your head around so if you're not sure when to use a layout ask yourself if the child routes of a game route have some repeating content in that case a layout makes perfect sense and also remember that we previously learned the data return from a layout's load function is available to child routes in your application which is really useful and of course you don't have to use group layouts to put this away in your pocket in case when you need it and focus on the fundamentals instead alright if you thought this was mind-bending in the next section I'm going to show you that individual pages and layouts can also change layouts alright so if you thought that group layouts Aren't mind-bending Enough let's talk about how you can break out of layouts so we learned that group layouts are nice for related routes but what if you want to use a different layout for a specific page or a layout and you can do that so for example if we go to the quotes let's find a beautiful quote so we can go to that quote and let's say for example that we don't want these other quotes and we want to use some other layout like the app layouts let's first find where it is in our code so you can go to routes app quotes going to be quote ID and quote ID so you can see here is the file plus page.swelt that inherits the Apparently also in here is the quotes layout and quote layout in here is the app layout alright so how can we use this app layout we can just rename Plus page.swilt we can use the add symbol and if you leave it black it's going to use the root layout since this is an empty string but we want to just use another layer so you can specify the layout you want to use which should be apparent in this case it's app so now when we save this let's see what happens how beautiful it is and we can even turn our hex back on so now you can see it only uses the app layout and how awesome is this and you probably looked up how to reset the layout in circuit and were confused when you read it you need to use a blankert layout which doesn't make any sense until you learn about group layouts and how to break out of layouts so if you want to reset the layout you have to have a blank root layout so if you remember let me just collapse all of this if you remember we have this blank layout right here and here is what silk is going to reference when you leave a blank layout and it's going to use the root layout and this is how you reset to root layout so I'm going to close it and let's see that in action so for example if I go to tags maybe I don't want this navigation maybe I just want a separate page that just shows tags and doesn't use any layout and I want to reset it to the root layout so let's see how we can do this so let's first find where tags are that scene app quotes tags right here so let me just create a new layout for tags I'm going to say plus layout sveld I'm going to just Define an empty script tag and let me see if it Auto Imports visualize awesome because I just want to show it to you and now we can give it a name let's say tags or whatever I had and then let's just say main I have this class space so it looks great and then don't forget about the slot let's save it and it works same as before but now we have a new layout and how can we reset this layout right so if I open the sidebar again and remember if I Collapse this so it's easier to see here is our layouts felt which is this file so now we can change this layout for the layout itself okay so now when we go to rename we can just say add this is an empty string and this is going to use the root layout all right so now when I do this uh how awesome it is so now you reset this layout the text layout to the root layout and now even if we turn on the hex you can see this is the tags layout and how awesome is this all right so now you know how to break out of layouts if you have to today I'm going to show you something cool and that is water circuit 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 swell kid 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 your 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 bore you with Theory and exploring every API of hooks I'm going to show you examples to spark 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 running a development server if you want to follow along you can scaffold your own project or you can just open stack reads 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 cell gets 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.servertis 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 handled which should be Auto imported from circuit and then it 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 destructure 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 as well kit 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 they soon have to research 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 would 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 learned 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 we 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 then we'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 pin 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 route 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 who's 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 gone so now inside the route you can just say plus layout server TS and now we can just say kit load like this and the loan function is going to be layout server load layout server load so this is going to actually what is going on let me just do a 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 we 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 but 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 you 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 two 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 just 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 to 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 hogs.clientes and the handle error function is going to run if an unexpected error is thrown 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 cons 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 Zod 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 so 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'll save it we can see our off hook 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 Welcome to the last part of the swelki series which is going to be about deploying a full Stacks valky lab we're going to learn a lot in this one from web hosting types or if you don't care about you can just skip to the end and I'm going to show you how to deploy a silky project but at the end of this we're going to deploy a full stack swelkit block project that's going to use Prisma postgradesql is the database which is going to be hosted on Super Bass and we're going to host the app on Versa I wanted a real world example because applications are more complicated than deploying your typical static blogger right in this project we're going to have blogs a dashboard which is just a mini content manage resistance so we're going to use server size rendering is going to be great but before that let's talk about web hosting types the reason why I want to cover all of this web hosting lore is because I want you to actually understand why I picked these Solutions instead of going for some other Solutions and we're going to briefly speed run the history of hosting and what led us to where we are today but of course you can skip this so just go to the hosting part which is going to take you five minutes probably let's talk about Cloud hosting basically all of Hosting is cloud hosting so you might be familiar with this traditional hosting providers like digital ocean remote or vulture but I call them specialized Cloud providers because they're actually focused on the consumer so if you go here you can see they have a really nice site so they're like focused on individual developers businesses and Etc so you can see it's very clear when you go to products droplets kubernetes and Etc you can pick a virtual private server or shared hosting so you're going to share CPU RAM and Etc with others you can see manage databases so basically you know what you get you also have Solutions here like manage WordPress Magento woocommerce and Etc so they really aimed at making this as user friendly as possible and then you have the second category which are the Titans of infrastructure they're basically like digital oceanly node and these others but AVS or Google cloud provider on Azure are basically the titans of infrastructure so look at this you basically the main difference is they offer thousands more services they have insanely larger infrastructure Etc and you need a degree to understand any of it so if you go for example to products you can scroll up for days so how can you make sense of this right and basically this isn't for mere mortals but this is for Enterprise and Etc and this sounds boring true but this is important to understand how we got to the next tier of web hosting which is going to be serverless so here we have the most popular ones for most people I think when you're with developers is going to be serverless or Jam stack and these are your Versailles netlify Cloud Fair pages so if you go here immediately here is advertising as a jam stack platform and jamstack platform means a lot to many people but basically it just means an art architecture where you use third-party apis to stitch together a site instead of Hosting everything on a single server and you have their sales and Etc and basically how do you make other sales so let's go back to AWS right so AWS has many offerings let's say for example you want to make this super easy you make a nice CLI you make a nice front end there are some of their offerings like AVS Lambda which is serverless and what you get you get our cell that's it and they also offer you a lot of more beneficial features like continuous Integrations for example when you push your code up to GitHub it's automatically going to redeploy and Etc you get nice previews and Etc and that's really the greatest developer experience out of all of them and then you have this other category that I didn't know the name of so I named it full stack platform so basically you might be familiar with Heroku and Heroku is like versel but for the entire stack right then it makes it easy one click deploys where you're back in front and Etc but Heroku has fallen out of favor due to recent pricing structure changes right but there's all other amazing Solutions now in this space you have a railway which is really easy if you want to just provision a database where you can host full stack you have render.com which is also awesome you have flyer which is also becoming popular and basically flyo is really interesting because it lets you deploy your app across the globe so as you can see here you can deploy not just your app but your data Etc so this is blazingly fast and this means that in a lot of cases that server side rendering can actually beat the speed of static and this is really awesome if this is something that you're interested in so you might be asking alrighty this is really so something why didn't you pick flyer or any other and this is another great selling point of serverless because serverless is so cheap because you don't have this server that you manage right like think of a traditional server it's just a long running process in your task manager or whatever you can imagine but serverless are just functions which get invoked by some action right so for example if you have an entire server and you only send one newsletter a week that's really a waste of electricity but if you using serverless it's only going to spin up when you need to send the newsletter which is really awesome and cheap this is why they have a lot of these three generous tiers because they don't actually give you a real server where you can wreak havoc right because the thing is with this sort of sites render flyo they actually give you a real server and this is really dangerous if you make it a free tier for everyone because people are going to do nefarious things with it so basically this is just all me rambling about just to say that this type of services require you mostly to use a credit card just to prevent that abuse and that's why I really chosen something like versel to host the app and I chosen Super Bass for the database and of course this is the next year I want to talk about because serverless has its own unique set of challenges you have all of these amazing great serverless databases you have super bass Firebase 49 jasura which I haven't tried but they seem like they're all into graphql if that's something you're interested in SATA sounds really interesting you have upstage for ready so you can use that you have plenty scale and then you have mongodb if you like using mongodb I really not a fan of Firebase because Firebase is proprietary and locks you in what is the benefit of something like super bass is that it uses postgresql so if Super Bass buys the dust or whatever they change the pricing tiers it really doesn't matter you can switch to Planet scale or whatever else you can provision another type of SQL database because we're also going to use Prisma that has many database adapters so your schema stays the same because the schema looks more something that looks like typescript instead of writing raw SQL or mongodb even yourself alright friends I'm super excited to show you how simple this is the only thing you're going to need is a GitHub account which I have a secret Smurf account here so you can use GitHub to log into Super Bass and to for sale inversell is going to ask you for permission to your GitHub anyhow because it has a tight integration with it so first we're going to create a database because that takes a minute and again we're going to use super bass to provision our postgresql database we don't really care about any other Super Bass features we're using Prisma another JavaScript library but of course if you want to use other Super Bass features you don't have to use Prisma so let's go and create a new project if you go to app.superbase.com create a new project I'm going to name it blog you can name it whatever you want and this is the important part we need to generate this password then we need to copy it I'm just going to create a new tab here copy the password don't link it to anyone and here you can choose a region close to you I'm going to pick this and then you can press free simple as that let's create a new project and this is going to take a second and that is going to take a minute to provision the database itself so you can see the project is created by the setting up the project this is a perfect time to set up the project so here is the example project with some simple instructions you really need to go here I'm just going to tell you what to do if you're following along which I hope you're doing so here inside of an empty project you're basically going to create a new GitHub repository and we're going to push this up so you can host it yourself and try it right so I'm going to use this command pnpx digit which is just going to copy over a GitHub Project without the history and it's really super simple so I'm going to complete joys of code 12K deploy this is the name of the repository and this dot at the end just means okay put it in this exact folder don't create a new folder and I'm just going to press enter and awesome it's fast like that let's install the dependencies and of course you can use any package manager you want but I highly encourage you to use pnpm so this is great and now if I close the terminal you should see here is the project so we need to rename this environment file to environment and be careful to not leak this to anyone this is very important and this is only required for local development because later when you hosted somewhere on yourself you need to enter your environment variable in their dashboard so here I can open the EnV and I already have some example here and by now this should be done so our database is provisioned awesome so if you go to Project settings database and you can see here's the connection string so you can get this but we want the connection string for the pooling because it's going to fix the problem when it comes to using a serverless database you really have to think about it just copy the string over we can copy it right here I hope you have your password because we're going to take the password copied let's close this because we don't need it anymore and now including brackets replace this and this is it boom you're done so let me just really show you inside the Prisma schema I set it up to use postgresql you can use any other adapter you want right the schema stays the same it looks like typescript beautiful Chef's case and you can see here we have something for authentication really it's not important here is the post schema itself so let me just close this and now I can even close this and now if you go to your terminal I'm going to press Ctrl L to clear everything so now we just want to create the tables from our Prisma schema and you can run migrate if you're in production but if you're just prototyping and trying things out you can say pnpx Prisma DB push and now this is going to create the table on Super Bass alright so let's give it a try and let's see what happens and now when you go to the table editor you're going to see here it populates the tables and here your posts are going to be you can even edit now Super Bass error out which is hilarious but yeah okay this is it you can see here is the database also I want to mention that you can also set up row level security because right now anyone with the anonymous Prisma key can edit this but you can look into this if you want another thing is that you can run the development server so you can say pmpm run Dev and everything should work great so first time running now we can go to localhost 5173 you should see everything working give it a minute to build everything you see everything working we only see the title because we don't have any posts but yeah this is just the full stack block app so you can see here is the blog which is going to be the search here is the dashboard right now there is nothing here so you get an error maybe I should have done some better error handling right but yeah it's really not important about and yeah this is awesome and you can even just go here and you can see here where the dashboard was right you can register here because you already have the access to the database but this is boring let's host our app on Versa at first let me just close this I'm going to close everything and on GitHub first we need to create a new project so we're going to create a new repository I'm just going to name it blog let's name it swellkit blog nothing else you need to do so you can just go here create new repository don't do anything here I'm going to press Ctrl shift G to enter this git mode and I can say initialize repository have the user terminal if that's spooky to you so the only thing we have to do here is ADD everything and let's just say feature add project nothing special we're going to use this sometimes I mix the GUI in terminal however I feel and this is what I love to do so I can go here I can just copy everything I can just say paste let's just do this and everything is fine because we're going to push on already existing repository and congrats now you have your own repository you can host it's clean and now you can use our cell but let me tell you one thing before we do that which you should do we're going to talk about adapters let's talk about that first so how do you host as well key project right so he has this concept of adapters by default if you don't have any adapter specified in the swell config you're going to see if you just close this you're going to see here it uses adapter Auto and this basically means when you deploy it to a supported platform like Cloud Fair workers netlify node static or your cell is going to know what the platform is and it's going to use the right adapter but you can of course do it yourself you can go here which resale recommends so let's do that prpm led development soil.js adapter for cell let's do that and we just need to replace that and that's it okay so now we can go here or sell here is a good tip I have for you so before you deploy to yourself just run pmpm run build and this is going to expose any potential errors like tax preparers because those are going to error out when you deploy your project so if you catch anything here it's going to save you so much time for having to redeploy constantly your app because of some silly errors right and you can see everything looks great this is the same output that's going to be on resale but it's not really the same and then when you're done with this you can say pnpm run preview and if you're really wondering how do I know these commanders go to your package Json you can always find the scripts here for testing and Etc they're all here so this is going to open it on Port 4173 instead of five you can go here you can see all right not brave search nice one you can just go here five or seven free and okay you see everything else okay this is internal error but it's because we output it using build this is not the development server so don't freak out okay so now let me show you how easy this is let me just stop all of this I'm just going to exit and now inside of the resale dashboard you just have to go create new project and this is going to load your repository if you're doing this for the first time it's going to ask you for the permission to your GitHub just say yes and then we can just select the repository because I'm on my legendary Smurf account I only have one repository so I can say import block and now here it already knows this is well kit because it's already pre-configured for you now the only thing you have to do is populate the environment variable here so let me just see I need to open the sidebar here you can see build and output settings you don't really have to change anything here because you have the preset here so it's feed build public and you don't have to care about this okay so now we care about this so now we just need to give it the name it's going to be database URL and I will just need to copy this connection string let me do this press add before you click Deploy on exit but you can edit after right because you can use this dashboard or whatever so now it's added and that's basically it so let me just collapse this and now I can press deploy and let me also close this tab and now this is going to take under a minute and another thing I want to mention is that if this is the first time you're doing this never be afraid of the built out of this might look spooky but this is the same thing we did here in the terminal right same thing as you run pnpm or npm run build this is the same output but it's using someone else's computer right so if you ever get an error don't freak out it's just running the command just stay calm read the error maybe Google it maybe it's something obvious you're doing something crazy right if you remember this is like exactly the same like we did here everything looks great and it's just doing its thing closing to the end let's see it's already done okay so this is it no errors great this is how simple that was let me just scroll up there's a lot oh it's actually not done but yeah it's going to be soon and the next time it's going to be even faster all right so now we get congratulations but let's continue to the dashboard so alsoever cell gives you a nice name for a preview but you can also look at other deployments so here we see our site is live so we can go to the deployment right here or you can change other settings like your node version if you want all right so let's see oh I clicked the deployment on accident I want to click on domains okay let's go to The Domain so let's see what's going on so we have latest posts and now when we go to the dashboard since you don't have an account right we can go register I'm going to say test one two three four and it should create a new account on Super Bass right and we already have a page hosted and if you want to enter your domain you can go here and somewhere under settings there is an option for domains and Etc alright so let's see what it's complaining about and if you ever get an error you can go to your deployments and you can go here I think and then you can see logs but you can also check it for functions you can see if something is wrong here but I don't think anything should be wrong here so let me just check what is going on here okay I don't know what happened now but we are already logged in and as we can go to Super Bass let's see user you can see here is the user and then we can go here we can create a new post and let's say Bob Ross ipsum of course let's go here and let's add some happy little trees like a post and then we can say happy little trees or whatever else title you want to give it happy little trees happy little trees and let's just paste this text I go to select this published let's submit it this is going to be added to our database here you can see despite this being server-side render this is really fast and if we go here let me just see this should work actually I'm really curious interesting must be something going on with your cell because I actually do not experience this basically this is going to work 100 you go to the blog that's where you can see here are all your posts you can search happy little trees we only have one post and let me just see about blog and here it is so basically maybe this is just so new that things need to settle down just give it a minute don't panic right things are going to work and now you can share this with your friends or whoever you want and you can log out and basically this is it now you've learned how to host a full stack project using circuit we use super bass to provision the postgresql database and of course then we deploy the entire project on resell in the next section I'm going to show you how you can optimize your site further using cache headers alright friends so how do we make our site even more awesome I'm not sure if you notice it I probably mentioned it but we're using server side rendering that means none of this is static but you can see our site is blazingly fast so how is that possible well basically the server-side rendering is slow is a misconception what is expensive with server side rendering isn't the creation of the HTML page or whatever but is the data you're trying to finish because fetching is expensive if the data is further away from you but how was static site works for example if I go here it uses a CDN or a Content delivery Network which are just servers across the globe that literally just take the assets from where you're hosting this so HTML video images and Etc and they put it closer to you so for example if you're here and you request some image for my blog then you're going to get this from this CDN instead of here and this is why static sites are so fast but then imagine that if you have some data like here in this case we're using Super Bass right and this is here in Frankfurt somewhere in Germany right and this is fast for me but it might be not fast for you over here or here what people are trying to solve this problem with is Edge Computing which is basically the same concept as CDN but it's using the edge to move the data closer to the user we're not going to use Edge today but we're going to use some simple HTTP caching basically we can just set cache control headers for a certain iteration which means if a thousand people visit your page you're not going to create a thousand requests doing the same work on the server but the CDN is going to be like oh I have this cached already I can just serve you this resource and then for example if an hour passed then is going to get it from the server again and this is really simple but powerful and really cache control headers aren't anything spooky so if I go here in the post here I have this section where I show you how you can set cache control headers and another thing I like about this is that you have to think about the content on your site so you can optimize it you can do whatever you want basically it gives you a lot more power freedom and flexibility and if you want to learn more about cache control headers you can go to mdn here you have some descriptions they aren't very useful to be honest but you learn a couple of these things and then you say so for example if we set max age this just means okay I don't want you to Cache this to the disk then you have this directive s Max H and this tells a share cache which is a CDN a Content delivery Network it tells it how much to Cache this resource and this is 60 times 60 so this is going to be one hour because 60 seconds times 60 minutes so if I go to the block here Let's see we have the latest post right and they're like thinking okay how often do I want to refresh this right and maybe you can put an hour because this really isn't that important and then we have an RSS here which you can also cache for an hour because why would you need to ask the server every second for this right this is like it's a waste of electricity and then you have some other things if you go to the block if you have a search and this just grabs the post and here I have some client JavaScript to just filter through them so this is nothing special and just ask yourself like how important is this right maybe we can also cache this for an hour because it's not important and then for the dashboard of course that gives us this eternal error for whatever reason I don't know what's going on but we can just ignore it for now in here you can be like okay I don't want to Cache anything that's Dynamic that's not the same right because I want the freshest data always and it's not really often used or public facing and then we have an interesting thing like an about which we can pre-render using page option in socket and we can even disable JavaScript by disabling client-side routing which are going to show you how and this is really awesome all right so now that we discussed this strategy another thing probably I should mention is that newsletter I don't really have any logic here but you can't you might be thinking if you look at this newsletter okay this isn't changing we can just pre-render it but you can't because pre-rendering isn't going to work if you use swellkit form actions because they require a server so we're just going to leave this alone really don't care about this alright so let me just use this pause so I don't miss type anything and have some silly errors so we just discuss the strategy what we want to do and I'm just going to use this to set the cache control headers so now I'm going to go to Source routes and now we can set the cache control header inside file so here is one for the route and here it is so here is where you get the publish post and really we just need to destructure set headers from here and that's how simple this is so now we can say set headers here you can set any header you want you can say x and you can say I'm going to give it to you and then you can specify your cache control headers if you want which is the thing we want so you can say cache control and again I also prefer to use this format like this so we actually know the time so we can say max age zero that's never going to change and we can say s Max H which this is really sometimes easy to get wrong and then let's just use this and I like to use this format but you can use an hour or there will soon but you can just use JavaScript for some easy maths okay so you can save this and then we have the blog route so we can go to the blog route as we discuss it and let's also cache this for an hour and let's just copy this part over so you'll have to repeat ourselves so we can go to the blog so we have the blog so here is the search for the site right if you go here see blog it's not cooperating today with me let me just see what's going on I'm just going to log in again see what's going on well yeah I hope this works much better for you because yeah apparently there are some difficulties but yeah we can just ignore it for now but we can just go here to the page server and let me just go here I'm just going to close this and let me just close the sidebar I'm going to copy over you don't really need this we just need to get the headers we can say set headers and now we can do this like I have it in the post right if you look at here here is the same thing so this is going to be an hour this is going to be an hour so for the Post itself really want that to always be fresh so when we fix a typo or something we just want it to be immediately reflected so we can set this to one minute so let's go here to the blog slog you can go here again same thing and copy this over you can just go here you can say set headers and then go here and just set it to 60 seconds you don't even have to do anything special here and I'm also going to need C programs yeah so let's not mess that up and then another one I think is the RSS so let me just see here is the RSS and this is interesting because this is at a root so if I go here where is the RSS here it is so here is something different because I'm using a standalone endpoint I'm already returning a new response which is content type and then we just need to do the same thing so we can just go here you can say hey cache is also on the CDN let's say Max stage zero this message and then you can set it to an hour or you can set it to whatever you want and also you don't have to just use these values you have access to geography right so you can make this conditional if you have a post that's older than seven days you can look at the publish time you can say okay if this post is older than seven days I'm probably not going to edit it often so cache it forever and then to bust the cache you can just redeploy to versal or you can use a web hook so let me just look at the about page when we're here here we're going to use cell kit page options so say for example I'm going to collapse everything just so you know where we are so for example in routes about I can just create page server TS file see what I created here so you can say export cons and now if you say pre-render this is just going to build a HTML page in advance and we can also disable the client router so this is not going to have any JavaScript at all because we don't need it for an about page and it's going to get rarely viewed anyhow so you can say client-side rendering false all right awesome so basically now we're done and now we can push the changes press Ctrl shift G I can go here and we can just add this let me just add this you can see feature for sale adapter or actually it's not a feature we can say build but it doesn't matter just commit and then we can say feature cache let's add all of these say commit and then you can say sync so now you're going to see something beautiful if I refresh this you're going to see here is going to push something in your commits and now for sale since it's hooked into this you go to resale dashboard is going to automatically redeploy so this is going to also take under a minute I'm going to close all of this and our cache is going to work so give this a second all right and this time it's a lot faster so you can go here and even have a new URL for that if you want and I hope this time we have more luck and less errors unlucky I know but it is how it is so this is another great thing that even if you have a branch in your repository you can push that up before you push it to main you can get a preview deployed to make sure you didn't mess something up on yourself which you should always do and then we can just open the link which is the link for this preview deploy and let's see things are already looking a lot better so let's see just login it should take a second and you can see it here so let's see our caching in play so when we open the network tab so the first thing I respect is we're going to get a cache missed because what I've done right now is I've just used client-side navigation right and your data can also get cache display but it doesn't really matter how someone is going to open your link they're going to go directly to that link right so first time you're going to get a Miss because it didn't Prime the cache so let's reset it and actually maybe I'm also unlucky let me just see I'm just going to do this and then let's just open this and we can see h0 so you just started and when we go here do these headers we can see it's a miss and now when we refresh this instead of asking the server is going to pull this from the CDN so let's refresh this and you already seen how fast this was and how awesome is this and this even isn't using static size generation right we're using server side rendering with some clever caching you can see h14 and now when a minute passes this is going to reset so let me just try my luck if I can go to the dashboard let me just make some changes here if I can I'm just going to give it exclamation marks let's save it submit it and let's go to the blog and now you can see 44 and now no matter how many times a refresh is going to be cached how awesome is this beautiful it's just using web standards right so here we say it's 54 we set it to 60 seconds right one minute so let's see are we close giving us this error but now let me just go here now you can see this is updated so now again this timer is going to start running and beautiful this is it alright so that concludes the sulkit series I hope you learned a lot about swellkit and now you should have more confidence to start working on your app if you enjoyed my content and want to support my work you can like And subscribe or become a patreon starting low with one dollar a month and if you need help or looking for a friendly Community you can join the joy of code Discord server as always thank you for watching and catch you in the next one peace [Music] thank you [Music]
Info
Channel: Joy of Code
Views: 74,246
Rating: undefined out of 5
Keywords: svelte, sveltekit, course, web development
Id: MoGkX4RvZ38
Channel Id: undefined
Length: 300min 40sec (18040 seconds)
Published: Tue Apr 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.