Do you struggle when adding users to your SvelteKit application? Are you having a hard time figuring out how to do form validation on client-side and server-side? Then this video is for you! Yo, what is up guys? This is SvelteRust from svelterust.com I teach Svelte, Rust and modern programming languages and today I'm going to show you how to add users using Supabase to your SvelteKit application and also how to make it look great with form validation using shadcn-svelte. So the first thing we want to do is create a SvelteKit application, add shadcn-svelte to it and then create a basic registration page. So now after you have added shadcn-svelte you want to run npx shadcn-svelte@latest add and we want the form. Let's create a form so that the user can create an account. So we want to go to src/routes and let's create the register/page.svelte So when we go here, register, we should be able to create an account. Let's go to shadcn-svelte documentation. Let's go to form and there's multiple things we need to understand. To create amazing forms, shadcn-svelte has done the hard work for us. So we can just copy the things from here and paste it into our application. Under the hood it uses Superforms and FormSnap. It also automatically displays errors. So let's say the password isn't long enough, it will display that. So the first thing we want to do is create a form schema. So let's copy this and this should be in schema.ts. So in our register folder let's create schema.ts. Here we basically define what fields we want to include in our form and what the fields need to look like. So let's rename this to email. And we want it to be a string and it should be an email. We also want a password which should be a string and minimum 8 characters. So that's our basic form schema. And because we want to validate this on the client side and the server side, we need to run the form validation on the server side. So let's create a +page.server.ts and you can just copy this. +page.server.ts. Just copy and paste this. Next we need to create our actual form. It might look a bit complicated but once you get used to it, it's really just boilerplate that you need to add for each form. So just copy this. So I will call this Register.svelte. Paste this. So I notice that we're missing an input, so let's go to the root of our project. npx shadcn-svelte@latest add input. So basically you can ignore this part. This is just boilerplate that you will have on your forms. So I noticed something interesting here. We get an error because in our schema username doesn't exist. We have email instead. Let's change this to email as well as this in the label and the name. Then we need to render this component in our +page.svelte. So step four, just copy this. And we want to import Register from Register.svelte. So register data equals data.form. So now we have our basic form. Let's also add the password field by going into Register.svelte. And we will copy this. So this will be password, password, password. We can remove the description. And instead of submit, create the account. So now we got our email and our password. So let's try and type something that's not an email. We get invalid email. If it is valid, it will show an error. Same with the password. It must be eight characters. Let's also make the inputs have a correct type. Type equals email. Type equals password. So when we type in the password, you don't see it. The last step of this is to add an action to handle the form submission. And then we will create an account with Supabase. Put these two into +page.server.ts. And then this default action, which will run when the user creates an account. So let's do a console.log(form.data). So when the user creates something, on the server side, we have the email and the password, which we can use to create an account with Supabase. Before we do that, let's try to make the form look a little bit nicer. So in our +page.svelte, we want this to be in the center of the screen. So this is what I'm going to do to put this in the center. So I'm going to create a div with a flex. We want the div to be the entire size of the screen. Then we want to put things in the center. That's emmet-mode, by the way, if you want to increase your development speed. I just put this in here. Now we have this form in the center here. I think it should be a little bit larger. So let's put this for max-w-md with flex-grow. And we want this to be full size, the button. So go to the button class equals w-full. And maybe some notice at the top. This is a register page. Let's do h1, register. Some margin below. We want the text to be a little bit nice, big and bold. So we can make this look a little bit nicer with some shadow, some rounding and padding. Now let's add Supabase to this so that we can actually create an account with Supabase. And display the user. After logging in, let's create a project. While this project is setting up, let's google superbase ssr sveltekit. And click on this first link here. And basically just follow this guide. So the first step is to install the packages. npm install supabase-js and ssr. In our .env file, we need to put the url to Supabase and the anonymous key. So .env, just copy this. And you want to replace the url with the url of your project, which you will be able to see here after creating a project. And the anonymous key, which will be down here. Next, we need to create a couple of files. So the first one is going to be hooks.server.ts. Just copy this to source hooks.server.ts. Next, let's add these types to our SvelteKit project. So copy this to app.d.ts. Like so. Then we want to create two files in routes. The first one is +layout.ts. So routes +layout.ts, paste this. And the other one is plus +layout.server.ts, +layout.server.ts. We want to put this in +layout.svelte. So we're going to paste this here. So we're going to paste this here. And we still want to import the app.css. Like so. And that's it. Now we have access to Supabase on the server side and the client side. So let's go to register +page.server.ts. Down here, we want to create an account with Supabase. So Supabase is stored in the locals, which we can get from the event. So Supabase is event.locals.supabase. Then let's destructure the email and the password from form.data. And let's do a call to Supabase. Supabase.auth.signup for our email and our password. If there is an error while signing up, we can show it locally on our server. And we can also return an error to our form, showing the user that there was an error. So return setError to the form on the password field. We want to show it to the bottom. And let's give them a message like, most likely, this account already exists. And we want to import this from SvelteKit SuperForms. Otherwise, let's redirect the user to the first page. For some reason, when I try to go to /register, Supabase thinks that I'm creating a new session. And in the +layout.svelte, inside the routes folder, they have this invalidation thing. But this is causing me issues right now. Comment this out for now. So when we go to /register now, let's try and create a new account. Create new account. So now we got redirected to the root. Let's try to display some data from the user here. So let's go to src/routes, +page.svelte. So to display the user's currently logged in email, we want to export that data. And we want to extract the user field from the data. So this will be available on every single page of Svelte. And if the user exists, let's display the user.email. Otherwise, let's display you are not logged in. So currently, it says you are not logged in, even though we created an account. This is because by default, Supabase wants you to confirm the email. So I'm going to disable this by going to Supabase dashboard, to SvelteRust, Authentication, Providers, Email, and just disable the confirm email. So you see my first user, it's waiting for a verification, so I didn't get logged in. Let's try again. Register, bro@bro.com. So now our user is logged in, and we can see the user's email. Let's add a logout button here. So I'm going to import the button from lib/components/ui/button. Logout. And to logout, we need to create a function. Logout. So what we need to do is to call supabase.auth.signOut(). But we don't have Supabase yet. All we need to do is get Supabase from here, and then we have Supabase ready. Then we want to go to routes, and we want to invalidate all, and import this. And then attach the logout function to the button. So when we click logout, we are logged out. Let's create the login page. So basically, you copy the register page to login, and just rename the things. So it's going to be login. Login to account. Page has failed, so we want to login, and we want to import login here. And finally, instead of signing up, we want to sign in with password. And if this fails, it's probably an invalid email or password. I'm going to go to /login. Roll one, two, three, four, five. So that's it. So now we got users working. We have a decent looking login and register page. So you can get Supabase and the user from locals on the server side, and on the client side, you can also get Supabase and the user from the data like this. So that's it. Make sure to like and subscribe, and leave a comment down below. If you enjoy these kinds of videos, and you want to build real web apps, head over to svelterust.com. All right. Goodbye.