2024 Supabase + Sveltekit Tutorial (0 to prod)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today I wanted to make a definitive video where I go through from scratch showing you guys how to put spell kit and sub base together to build a production ready app we're going to go over the local Dev experience which is admittedly a little tricky on subbases side I think that their documentation does need a little work in this area but otherwise the actual experience once you get it working is beyond phenomenal and is really something worth using now before we get started there are a few prerequisites that you'll need to have installed in order to get all this working so first and foremost you need to have docker desktop installed as well as the superbas CLI you can get both of those they're linked down below the superbase documentation is great on those um obviously you need to have node installed and actually we're going to be using bun for this I just prefer Bun over node it is much faster locally it works really well and I'm most I think I migrated like all my projects except for the giant T3 turbo mono repo I have to work with everything else is on bun at this point so I'm going to use that for the package manager outside of all that stuff make sure you have your code editor this is not going to be like a beginner tutorial on like hey here's how you use spell kit here's how you use superbase all that stuff we're really just going to be focusing on how to actually use these together and get a project set up so that you have a nice little template to actually create your app so with all that yapping out of the way let's get into the tutorial so let's start this out by creating our spel kit project I'm going to go ahead and run npm create spell at latest I'm going to go ahead and just call this um sub base spelt kit tutorial and then I'm going to go ahead down in here I'm going to say I want a skeleton project project I want a typescript syntax let's add eslint prettier I don't want playwriter of v test and then of course we're going to try the spel vibe preview they say it's unstable they say you shouldn't use it in production I don't give a I'm using it in production it works great so we're going to go ahead and do that we have our new tuto we have our new project here I'm going to go ahead and CD into superbase uh spell kit tutorial I'm going to go ahead and open this up in vs code go ahead make sure that this is nice and zoomed in for the tutorial I'm going to go ahead and start by deleting this npmrc we don't need that cuz we're not using npm now we're going to start with the superbase stuff that's probably the easiest place to start here so remember you need to have the superbase CLI installed so I'm going to go ahead and run super base andit that we'll go ahead and create the new thing we're going to say yes um we're not going to be using any of the edge functions here so we don't have to worry about Dino but might as well so now we have our new superbase directory and the first thing I want to go ahead and do is get this config toml set up correctly now this is one of the things that is by far the most confusing about working with superbase locally so I want to try and dispel a lot of the issues that I've personally had and I've heard a lot of you guys have so first and foremost the API we really don't have to care about this the DB don't have to care about this real time don't have to care about this studio want to make sure we keep that uh in bucket none of this stuff really matters except for off off setting up off locally is kind of hard to figure out but once you do it's really really simple so first and formost for most we want to change our site URL over here to Local Host 5173 going to do the same thing down here to actually I'm going to change this as well so we're going to do Local Host 5173 and we're going to change this as well to Local Host 5173 CU we're in spell kit not nextjs so uh everything else here is good everything else is fine um for off. email we can leave this be I personally really hate email authentication we're not even going to be implementing it here I don't want your passwords in any site I personally go to that uses email authentication I pretty much instantly bounce so I don't want to waste our time with this we're going to close that up but for the o. external this is where it gets important so we're going to leave o. external. Apple blank we're going to go down here and add in some new stuff so first and foremost we want to do off. external. GitHub and this is the easiest off provider to set up and it's just a really great uh example for this so we're going to first and foremost say enabled equals true we're going to go ahead and say our client ID is equal to EnV and then we're going to go ahead and call this GitHub client ID uh next thing we're going to go ahead and do is we're going to set up our client secret and we're going to set this to be EnV uh GitHub client secret the autocomplete new so then the next thing we need to do is set up our redirect uh URI now for our redirect direct URI this is where it gets a little tricky we actually want to set this to um HTTP col1 127.0.0.1 colon 54321 slv1 callback whenever we redirect from GitHub we want to redirect actually back to the um we want to redirect back to the superbase local server and let it handle the authentication from there so this is a tricky piece that is hard to find that like this is what you actually need to put here but this is the key we want to put this here for our redirect URI and then after that we're good so now that we've done all this and we have our uh GitHub set up we need to fill in these the client ID and the client secret so I'm going to go into my GitHub account here so I'm going to go over to my profile I'm going to go into my where that it's settings and then we're going to go down here into my um developer settings we're going to go into ooth Apps and then I have I have a ton in here um but I already have one in here that I call superbase spell kit local all you have to do is create a new ooth app I'm just going to use this one whenever you create this you're going to get client ID here and then you're going to want to grabb your client secret we'll generate a new one in a second but the really important piece in here that you need to set is when you're setting the homepage URL should just be Local Host 5173 Give It Whatever description you want then the really really key piece here is that your authorization callback URL needs to be this so it needs to be this um I'll zoom in on this real quick so you can see it it's 127.0.0.1 colon 54321 slv1 callback this is really important so make sure you set your call back to be this set your homepage URL to be this go ahead and create your application then once you've done that you want to grab your client ID here so I'm going to First grab this we're going to go back to um code I'm going to go ahead in here and I'm going to create a newv file I'm going to go ahead and say GitHub uh client um ID is equal to that uh go back over here uh yep and then I'm going to go back over here I'm going to gener create a new client secret so now that we've copied our client secret we want to go ahead and say GitHub client secret then we're just going to set that equal to this guy I'm going to uh flush all these Keys before this goes live so don't worry about me leaking stuff so we have our client ID our client secret and now our config dotl is all set up so that is one of the trickiest parts of this which is now all set up and ready for you and you can just go ahead and actually run your off servers but we're not done setting up yet the next thing we need to do is the database now superbase has really good client side SDK for interfacing with our databases you can use stuff like Rowl security to go ahead and secure your database and interact with it directly from the client but I personally really don't like that way of interfacing with my database and working with it I much prefer to use a normal or and use it like a normal database so we're going to be using drizzle here drizzle is my om of choice um I really like Prisma Prisma has a lot of good stuff to it but um the front loading cost of just getting Prisma set up is such a pain in the ass that I just I don't want to deal with it so we're going to use drizzle so to get drizzle set up um I'm actually going to use the show you guys the documentation and kind of just show you my thought process and how I go through this because I don't have any of this memorized so we're going to go in here into uh drizzle we're going to go into the documentation we're going to go into postgress we're going to go into super base we're going to start by copying this first line I'm going to go back to my terminal I'm going to go ahead and paste that in here and then I'm going to go back over here I'm going to do bun add- D drizzle kit add those guys in here then once we've done that I'm actually going to go ahead and set up my drizzle kit file here so if you go in here to the quick start I think they have a good example in here yeah they do awesome okay so we're going to go ahead and just copy paste this so this is from the quick start section on drizzle kit we're going to go back into our project in the root directory here I'm going to do drizzle. config.sys schema and where our out directories are so our drizzle is going to live in Source lib and then we're going to create a new directory in here called DB um and then we're going to create a new file called index.ts and we're going to also create another file called in uh schema. TS this is typically how I set up my database so in my going back to our little drizzle. config here I'm going to say my schema is going to be in/ Source SL lib slash DB schema. TS and then our out directory here we're going to get a little Fancy with this and we're actually going to generate migrations directly for superbase now when we're working with superbase locally one of the cool things we can do is whenever we whenever you start up your local superbase server if you have a migrations directory in your superbase directory it will automatically apply those migrations to your local database so we don't have to do like DB push or anything like that we can manage our database there and we can also use that to deploy our database later on and that's we'll include that at the end of the video I think um showing how to take this to prod is really important so I'm not going to leave that out so what I'm going to go ahead and do is I just pasted a bunch of stuff in here so the first thing we Chang is we set our out directory to be/ subase migrations that means we're going to generate all of our migrations into here then the next thing we want to go ahead and do is we want to set our database credentials to be Local Host 5543 21 postgress postgress super base now this is really kind of optional you really don't need to have this in here but I like to include it for complete sake so now that we've done all of this we actually have our full superbase instance ready but we need to create some data to actually we need to create a schema to migrate in so I'm going to go back here into my source directory into my lib into my DB and we're going to start in the schema so the first thing I'm going to do is I'm going to say export const profile table equals um uh PG table I'm going to call this profile I'm going to go ahead in here and we're just going to set some basic fields for this little example app we're going to have a profile for the user we're going to update some fields on there using form actions to show you guys how those work and um really the point of this is in a lot of real apps I typically find myself having a separate table within my normal database that's like a profile instance because I want to store stuff on there I want to store user settings I want to store have like a link to all the other tables I really like having this so I'm going to go ahead and say ID is equal to um uyu ID we're going to import that from post addess core just going to call this ID we're going to say this is a primary key we're not going to have it auto set because we want to set that ourselves this ID is actually going to uh reference The UU ID in the off table we can't manually set that but that's how we'll actually do it so then the next thing I'm going to do I'm going to do first name is equal to um text nope not that text we're going to do text from PG core just going to say first name then we're going to do do not null I don't like null values if I can avoid them also going to have last name so going to have email um and yeah that that's good enough for this example that's really all we need to have so we have this profile table here and go back to this index.ts we're going go back over here to the drizzle documentation I'm going to jump back up here to the docs we're going to go back to postgress back to superbase and we're going to jump down here to this little index.ts here I'm just going to copy everything out of this I'm going to paste it in here um that's not correct that's not correct um that's not correct we're going to actually export this database and within our drizzle we also want to import Star as schema from schema so this will give us nice types for the drizzle query client which was a really nice thing that they added recently pass in our schema here and the last thing we need to do is get our connection string so I'm going to go ahead and just say this is going to be equal to database um you URL and we will import this after we've actually run our Dev server once we've run that this will be generated as a static type in spel kit and we can import that we don't have it yet so we're just going to wait so with that now out of the way let's go ahead back into our package.json and let's create some helper functions in here I like having these so the first one we're going to create is going to be DB generate uh so we're going to go ahead and say drizzle kit generate so we're going to paste that in here and then that's really the only one we need so now that we have this command I'm going to go ahead back over to my terminal I'm going to do bun run DB generate then this will take a second and it will create this new migration so going back into our project we go into super base we go into migrations we can see we have our first migration here it's super basic all we're doing is just creating our profile and we actually need to add something to this we're going to do alter table um profile enable row level security so what this will do is this will block off public access from the public h GTP API that super base exposes again I don't like I don't like the client side SDK for that stuff I know some people do it's just not for me so we're going to go ahead alter the table enable the row level security block that off and we should be good so I'm going to go ahead close this up and I think with that we are basically ready to start our server okay so we're going to run sub start and end up actually getting an error here it's um oh I forgot for GitHub it's not client secret it's actually secret so we're going to go ahead in here and we're going to go back to our config dotl we're going to go back down here to external GitHub and we're actually going to change this to be secret is equal to env. client secret there we go okay so now if we go back in here and we do super base start okay there we go okay yeah I think my Docker was just up finally when I clear all this out and I do super base start this will go ahead and actually spin up our database it will use those migrations app apply them locally apply all of the Au stuff locally and we should have a nice environment prepped in ready so give this a moment here let it set up our schema let it go through and do everything okay awesome so with that out of the way we now have our local subbase instance working if I go ahead in here to our studio URL pop this up we go into our table editor you'll see we've got our nice profile here we have it's protected by RLS we have all our stuff working in here and we're ready to actually make the app so let's go ahead back down here let's go ahead and copy paste this database URL we're going to copy this boy here I'm going to go back into my project I'm going to go into myv I'm going to say database UR L is equal to this guy and now finally let's go ahead in here and let's do bun I let's do Bun Run Dev so now I'm going to go back in here I'm going to go into my database I'm going to go in here I'm going to now import this from static private and then if we go to 5173 we'll get welcome to spelit and I'm going to go back over here and close this I'm going to go back into our project here I'm going to go into roots and then I'm going to go ahead and create a page. server. TS we go ahead and say export const load equals async so this is our serers side load function here you go ahead and say const um profiles equals await DB where I import from that lib db. query. profile table. find many then we're just going to go ahead and return the profiles we're going to go onto our page. spelt we're going to go ahead and add a script tag up here I'm going to set my Lang equal to TS and finally I'm going to say const data equals dollar props to grab our data from the page. server we're going to do inspect um data. profiles we're going to go back into our terminal I'm going to open this back up and inspect element and we should see no profiles beautiful it worked exactly right so we are all good our database is working and connected so now let's get subase set up and running for our spelit app so this is where it gets a lot easier and where the documentation is helpful but I still want to go through this in the video and make sure that you guys have a complete video here to actually show you how this works so I'm going to go back here and I'm just going to go ahead and look up um superbase SSR package setup just going to look that up we're going to create a superbase client for SSR I'm going to go into the spel kit guide I'm really glad that they have this and we're just going to follow it so I'm going to start up here with my subbase Js and subbase SSR we're going to copy this right here going to stop my Dev server do bun add these two homies then we're going to go back over here to ourv I do EnV not. env. local I don't know why I just don't I don't who cares um so we're going to do these going to copy this guy here and go ahead into ourv going to go ahead and paste those two in here now for our superbase URL this we can go ahead back into our terminal and if we do superbase status we'll get all of this information so I'm going to start here by copying this API URL we're going to paste that in here I'm going to clear this out here and for our Anon key I'm going to go ahead and set that equal to this guy right here so we're going to copy him and I'm going to paste him in here now that we've done that we're going to close up this Dov I'm going to go ahead and do Bun Run Dev so that we get the type safety on our EnV variables then we're just going to keep following it so the first thing I'm going to go do is go down here I'm going to go into and we're going to make our hooks. server. TS so I'm going to start over here I'm going to copy just copy paste everything from here I'm going to go into my uh Source directory here I'm going to create hooks. server. TS go ahead and paste that in here and we're going to get a bunch of type errors because we don't have our types in our app. D.S but most of this is actually pretty much correct so just going to leave that how it is we're going to go back in here and we're going to go into our type defs I'm going to copy everything here I'm going to go into my app. DTS I'm going to actually add to this so I'm going to paste it up here um oh wait no they do it right so I'm going to go ahead and just delete everything here and I'm just going to paste in everything from there so we'll get our session type our client type and our user type in uh properly type our locals and our server should now be working correctly beautiful it is so perfect this is working just fine and now we can go back over here so now we're going to go ahead and create our browser client with our layout. TS so I'm going to go in here I'm just going to copy everything from this again we're going to go into our Roots we're going to add a Plus layout. Ts which means that this can run both client side and server side but really just think of it as client side so we're going to go ahead and paste this in here uh we have this nice is browser check to ensure we're in the right environment and if we are we go ahead and create our little browser client in here everything is good we're going to go back over here and also grab this layout. server to add our session to our layout so I'm going to go ahead and copy paste paste everything from here so we going to go back in here and I'm going to do Plus layout. server. Ts go ahead and paste that in Here and Now that'll get rid of our type error in here because we know that we have our data. session and now we should have all the context we need to actually use subase in our app I believe um oh yeah one other thing we can add in here which I'll go ahead and add this because it's good practice is we want to have a little listener in here which whenever we change our off State we go ahead and invalid validate our authentication and log the user out so I'm going to go ahead in here I'm going to copy paste all of this we're going to go ahead and add a plus layout. spelt we're going to paste all this in here and I'm actually going to change a couple of things so first and foremost I'm going to add in this Lang equals TS now we're going to do this in runes mode I don't want to leave you guys in the old spelt 4 thing we're going to do this in runes mode because that's the that's the new stuff so I'm going to go ahead and say um const data equals um dollar props we're going to delete this um we are going to go ahead and uh delete this and we are going to go ahead and switch this on Mount into an effect so this will now be an effect Rune we're going to delete this yeah we had a little override here where we had data declared twice so I'm just going to rename this to props data I'm going to go ahead and say props data equals all this stuff then we're going to say props data. session and now I believe we should be good and the last thing we need to change in here is spelt 5 does things a little bit differently so I'm actually going to in my props I'm also going to add in a new thing here called children so children is the new replacement for slot so I'm going to go down here we're replace this and we're going to say at render whoops I can't spell and children there we go so now this will render out all of our child Pages we could add in a div up here um put something here and then be like H2 be like hello from uh layout or something just to show you how this works so this is just the normal slot just a little bit different a little bit more explicit and it's probably better um so now when we go to our Local Host 5173 hello from layout will work we get our welcome to spel Kit page and everything is good so now that we've done that let's go ahead and Implement our signin with GitHub so the first thing we're going to go ahead and do here is I'm going to go into our uh the flows here on the docs we're going to go down to GitHub and we're going to copy paste some more code so and we're going to run this with the uh serers side flow so I'm going to go in here to the second method here click on server and we're going to go ahead and copy paste all of this so I'm going to copy paste this we're going to go back over to our project here we're going to go into Roots we're going to add a new folder called off we're going to go ahead and add a new uh file uh folder in here called login I'm going to go ahead and add in A Plus page. server. Ts we're going to go ahead and say export const actions is equal to this we're to say our default action is going to be async we're going to go ahead and grab our locals go ahead and do this I'm going to paste in everything I had there we're going to replace this superbase with locals. superbase I'm going to go ahead and we're not going to handle errors for this it's fine U I'm going to replace this provider option with GitHub we going to go ahead and change this redirect URL down here to http colon Local Host uh 5173 slash we're just going to do the homepage here then we're finally going to go down here and we're going to say uh redirect add this import from spel kit uh we need to update this to go ahead and have a 307 in here and then we can go ahead and finally just do return uh success is false because if we get to this point it did not work but at that point we should be good so now what this will do is this will initially initiate our server side offlow we can go through and do all that stuff and before we go ahead and do the client side code we first need to go ahead and add the call back cuz remember whenever you do ooth we're not going to go deep into how this all really works but really what you're doing is you're going to GitHub land you uh you create your oo flow you get your token you go to github's site and when you log in on github's site they send you back with a token and that token basically validates like hey they signed in correctly so we're going to go back over here I'm going to go down here to this off call back so I'm just going to copy paste everything right here we're going to go into our um off slash callback here we're going to go ahead and add Plus server. Ts just going to paste everything in here and I think that should handle it that should get what we need oh wait I forgot we can also grab URL so yeah that'll give us everything we need in here okay so now that we have this I'm actually going to make one more change to our login here I'm going to go back over here and instead of just doing this we're actually just going to go ahead and say um we want to do here is we want to go up here we're going to add in a URL here because we have access to the URL context we're going to say url. host want to send you back to oh no sorry not host. origin so we're going to go ahead and just do the origin right here send them back to the homepage basically and with all of that we should be good to make our client side code now I want to make this look a little bit nicer so that it looks a little bit like a real app so I'm going to go ahead and add in Tailwind in Shaden for spel so I'm going to go ahead into the documentation for Shaden spel it's my favorite uh UI library for spel kit I'm going to go ahead in here I'm going to copy paste the uh second command here we're going to go ahead and select bun cuz that's the package manager we're using stop the server paste this in here let it run through and initialize our new Tailwind um preconditions failed uh yes we do wish to continue uh yes uh no we don't need topography um it'll install everything awesome uh we're going to go ahead and run bun I going to go back down here uh we don't need to change our path aliases um now we want to go ahead and initialize Shad CNF so I'm going to go ahead right here I'm going to add in bun I'm going to go ahead and paste this in here I am using typescript we'll just do default style I prefer neutral uh that'll work that'll work that'll work that'll work and now we have our Shaden initialized um I'm going to go back down in here and now I'm going to go back to this site and want to add a couple components so the first one we're going to go ahead and add is button this one's really useful just going to go down here say bun paste that in here um we'll say yes I'm going to go back over here I'm going to do the next one I want to do is going to be label so I'm going to go to label here I'm going to go ahead and uh copy this paste you in here um yes we want to install I'm going to go ahead and do input go ahead and grab you we're going to go ahead and paste this in here go ahead and say yes then finally we're going to go ahead and do card uh the this should be enough to make a semi a semi-competent UI for this little example so we're going to go ahead and add in this card yes we want to install now with all of that done we're going to go ahead and do bun runev once more I'm going to go back to our website it should look oh yeah so when you restart your server I think it like in the layout. spell it auto added in the slot so we need to go ahead and close you up we're going to go back to our layout. spelt we go all the way down here and it automatically added in this slot we don't want that we're just going to delete him there um make sure yep it added our app. CSS we open this back up yep it'll look completely unstyled but that's cuz we're now in tailwind and it's all working so I'm going to go back here I'm going to go into our page. spelt I'm going to go ahead and delete these here we're going to import button here so I'm going to import this button from component button we are going to say HF equals off/ login we're going to say log to the site um we're going to go back over to our homepage here give it a moment to load we're going to go ahead and log in to the site oh so there's no page attached so when you click it it won't do anything but if we go back over here now and we go to off and we go to login and we go to plus page. spelt we're going to go ahead in here and we're going to let's make this look kind of nice so I'm going to go ahead and add in a new card I'm going to import this from component card we're going to add in card header uh grab that also from card um we're going to go ahead and say login to the site um we're going to go ahead down here into card content and then we're just going to go ahead and add in a button here um we'll also wrap this in a form we'll change that in a a moment here so we're going to delete this down here paste that go ahead within this button we're going to want to also import this here we're going to want to say Lo sign in with GitHub we're going to want to go ahead and set the type of this button to be submit because we want to submit the form because we're firing a form action here actually we don't even need to have action here we just need to do method equals um post and now with all of that nonsense hopefully done um I'm going to go ahead back into here I'm going to go back over to our site I'm going to go to log into to site okay so you'll notice actually here I didn't even notice this they changed this on the documentation so if you go to the login to site and you go to a login it just nothing will work and that's actually because there's an offguard on this now so we go back into our hooks. server. TS we'll go ahead and just um going of close up this super base instance and if you look down here we have our offg guard here so in here basically what we're doing is we're just checking if they're logged in and then if like basically having a bunch of private directories here and I I just don't want any of this I don't typically find myself doing these guard functions that much it um you can leave this in if you want to and set it up but I'm actually just going to go ahead and delete this we're just going to go ahead and remove the offard back here I'll leave the sequence in so if you want to add in more things in sequence you can but otherwise we don't really need that so I'm going to delete this redirect now if we go back over here and I go to log into site oh it's probably just not rebuilding so actually what we need to do here is probably just go in here and just delete our spell kit file CU sometimes this happens in spel this is one of the most annoying things about the framework is every once in a while it just won't properly rebuild so we're actually going to do bun eye again uh let it all reinstall and then we're going to do Bun Run Dev we're going to open up our Local Host instance here and this really should work now right what the okay cool there we go okay so that that fixed it so yeah so that was that was the problem so basically what we were doing is since we were just Pro passing all of the props data into this effect it was constantly rerunning the effect so what we want to actually do in here is we just want to destructure these grab subase and session from props data pass these guys right in here uh to this and then that should fix it so that was a long way of saying like make sure that you change those two things so that you can properly get into your uh route so now we can finally go over to log into the site we will have this pretty ugly card I haven't really done any diing to it now if you try this right now you'll actually notice we made one more mistake here so when you hit sign in with GitHub it'll give you the wrong thing here what we actually want to do here is we want to redirect to be url. origin plus offall back we want it to go here um we want to go ahead and do this here sign in with ooth all that stuff should be good okay yeah awesome finally so now we go here we log in with so one thing that you're going to notice actually is I kind of screwed this up when I initially did this earlier I was just thinking oh yeah we'll just do this within the form actions and stuff but that kind of gets screwy with all the different httv verbs that get thrown in there so I'm going to make this a lot easier and just make a little get request here that will run the call that will run the authentication flow so we're going to go in here to the login directory we're going to go ahead and add in a GitHub folder here we're going to go ahead and add in a a server. TS we're going to go ahead and say export const get and then this is going to be equal to an async file to an async function we're going to go ahead and say locals and from locals we're going to grab superbase out of here we're also going to grab the URL and we're going to go ahead down here we're going to say const uh data equals await superbase do off. signin with oo we're going to say our provider is GitHub and we're going to say in our options we're going to say redirect to and then we're going to do url. origin and then all/ callback and then we're going to go ahead and say if data. URL redirect to the data. URL um we don't need all of that that it just popped up there delete this otherwise we want to go ahead and just do a redirect to um 307 and then we will do slof SL error uh we haven't created that and we'll just hope that we don't have any AU erors but this is where you would go through and Implement all that stuff so now that I've finally done all that stuff we're going to go back over to our project here so we're going to go back in here we're going to go to this page now we need to change this client side so we're going to go to our page. spelt I'm going to delete this form I'm going to change this button to instead be a little um to have a href we're going to set this to a/ uh login SL GitHub we're going to go ahead into our page. server we're going to delete uh actually we can just delete this no we'll leave this in here uh but we'll just delete all of this flat out um we're just going to do this now when we go back in here we go to sign in with GitHub it'll go through and it will log me in I've already logged in with GitHub on this computer so it didn't show GitHub but if you're not it will take you there and you can do this so now if we go back into our um homepage here and I'm just going to go ahead and um do inspect we're actually going to do data do user we're going to inspect the user object here we're going to inspect element go in here you can see we have an object right here that says we have an authenticated users just like that we now have authentication working so the last thing we're going to go ahead and do here which should be pretty quick I really hope is going to be um just implementing some basic crud logic uh getting this to look a little bit nicer adding in a couple off checks and then we'll go ahead and deploy it so I'm going to go back over here I'm going to go into my um where is it uh where do we want to start this let's let's just do it on the homepage so we're going to add in a uh big old if in here so we're going to go ahead and do a hashif data. user um so the user object is optional here right I believe data. user oh come on uh we're going to do else we're going to close our if right here and we're going to say div you are logged in um whoops I have these flips I'm just going to flip these real quick and now if we go back over here it's going to say you are logged in so we have this right here so now that we are logged in we're going to go ahead and actually add in some logic here so let's go ahead and create a new card let's go ahead and we need to import this from our card component we're going to say uh card content it's going to be in here we're going to go ahead and say um or we'll add card header we're going to go ahead and say um manage your profile and the three Fields we're going to have in here we're going to add in a div we're going to add in a label here so we're going to import that from our label here we're going to say um email and then we're going to add in an input here um we'll just have this just be an input for right now that's fine um we're going to just copy paste this and paste this and we're going to do a first name we're going to do last name here and with all of that we're going to go ahead and add in one more div down here we're going to add in a button we're going to say uh update we're going to say type equals submit and we are going to go ahead and actually wrap all of this in here in a form so we're going to go ahead and do this we're going to go all the way down here we're going to delete this guy down here and now we have what we need so this is all good but the next thing I want to do is I want to go ahead and kind of change a couple things about the authentication to get it a little bit more production ready so we're going to go ahead in here we're going to go into our lib directory and let's go ahead and add in a new utility function so I'm going to go ahead and do make a new off folder in here I'm going to go ahead and call this index.ts and now I'm going to go ahead and say export const get or create user profile where this is going to be async this is going to take in um a our locals object we want to say app. locals and we're just going to do this and then the first thing we're going to go ahead and do is we're going to say um if not locals. user we're just going to go ahead and return null the next thing we want to go ahead and do is we want to say um const per profile equals await uh db. query. profilet table. find First and we're going to say where going to do EQ uh profile table. ID is equal to locals. user uh. ID so now we're going to say if current profile we just want to return the profile and otherwise we want to create a profile so we're going to just go ahead and tab this in um no we'll do const new profile equals await db. insert into the profile table or say our values are just going to be an object our ID will be locals. user ID and then for now we're just going to leave our first name blank we're going to leave our last name blank but for our email we want to use locals. user. email and now uh this is potentially undefined so we'll also give that an option to just be empty so now that we've done all of this stuff we're just going to go ahead and return the new user profile we'll make this easier and we'll just go ahead and just do um this and then finally we'll go ahead and just do um const and a new profile equals a wait fine first same query as above and then we'll just return a new profile and we know that this has to not be undefined so we will force this to be real or I guess um if not new profile file there was a new error in creating that so we want to actually make this a spel kit error so we're going to delete all of this in here so we're going to say error then we're going to go ahead and just say um error is going to be a 500 could not create the profile and then otherwise we will just return the profile that will be defined so then here this should return a promise of either a profile object or null and this is super super helpful for basically working as a guard function so I'm going to go back over here into to my uh Roots here so instead of grabbing profiles we're actually going to say const user Prof uh profile equals wait get or create user profile and we need to grab our locals here we're going to pass our locals into here and then we're just going to return user profile going to delete this and then now within our page. spelt I'm actually going to change this to be if dat. user profile this is more this is a much more useful thing to work with here so I'm going to go ahead and delete this um everything should be good here so if we have a profile we're going to fill this in so what you're actually going to notice in here when we make that change is actually that the profile is now disappearing so we now just have log into site and the profile is going to be null for some reason so what we want to go ahead and do here is we want to go into our um want to go actually back into our get or create profile we're going to go in here and we actually need to change a little bit about how this works so one of the things that's a little interesting about how we have this setup is we have this function up here called get save session so this get sa session is how we can get out our user and how we can get out our session so in here we don't actually have our user set to anything and we don't actually have our session set to anything because we haven't called get save session yet so what we need to actually do in here is I'm going to go ahead up here and I'm going to say const session uh actually we just need to get user so we're going to say const user equals await uh locals. safe get session so now down here we're going to replace this locals. user we're going to replace all of these we're going to replace this guy going to replace this guy this guy this guy replace all of these in here with that and then with those fixes in place now we go back here we will have our profile incorrectly you will see my profile in here everything is well and good so now that all of these random little edge cases have been figured out I know that this is a lot it's kind of chaos getting this set up I will have this entire finished project linked down below it'll be eventually this will probably be a template we definitely need to do that that's something that's been on my list forever and I think we're finally making steps towards getting that done so this will exist at some point so we're going to go ahead down here I'm going to go into my page. spell here and let's go ahead and actually make this work now there are a lot of different ways we could do this but I want to show off some uh a lot of the progressive enhancement stuff to give you guys some more context on on how to do that this is not the most efficient way to actually implement this but again I just we're going to make it a little weird just for the sake of showing off some Concepts so first and foremost we need to set up our state variables I'm going to say let first name equals dollar State empty string let last name and we're going to say let email equals State now I'm going to go down here into my inputs I'm going to say bind value equals email going to do the same thing in here we're going to do bind value equals first name and we are going to do bind value equals last name finally so now that we've done that we can go ahead and work with our state variables but we want to populate these based on our data so I'm going to go down here and I'm going to do dollar um effect let just populate these on Mount basically I know um I use effect more than I probably should but whatever it you know it works um I'm going to go ahead and ALS so D structure up here I'm going to do const um user profile equals uh data just grab this out here uh we're going to go down here and also change this to just be user profile and say if user profile and go ahead and do first name uh equals profile name set all these co-pilot knows what to do and now if we go back into our page here you'll see my email is populated with my real email and first name and last name are empty CU we don't have anything there so now now let's go ahead and make the backend server side function to actually work with this so I'm going to go to my page. server. ts we're going to go ahead and do export const actions equals uh default async we're going to need to grab in our request object and we're need to go ahead and grab our locals object I believe yes go ahead and do this first and foremost we want to go ahead and say cons um user profile equals await get or create user profile we'll pass in local here uh if not user profile we're just going to throw an error here we're going to do a spel kit error we're going to say uh 401 and then you need to be logged in now I'm going to use a package here that I really like that makes uh form data a lot easier to work with we're going to go and do Zod form data this is a really useful package which I found uh very lightweight very simple which we can go ahead in here and use this to kind of create create a schema and then quickly safe parse our form data uh probably should make a utility function out of this eventually but for now this will work we're going to go back into our terminal we're going to do bun add Zod form data and Zod we're going to go ahead and just uh do Bun Run Dev once again going to go back in here and I'm going to say um con schema equals zfd d uh it doesn't seem oh wait doesn't get it yep uh do form data first name which is going to be a string a last name and actually these aren't strings these are actually going to be text Fields because instead of mapping to normal typescript types it's going to map to form types so we're going to grab these text objects and then we're going to say const um data comma error we're going to say equals uh schema parse and we're going to pass in uh request form data so we're going to do schema. saave parse we'll pull out our um data from here this data will be either here or not defined we're going to go ahead and do if uh not data and go ahead and throw another error in here and we're going to say 400 invalid form data then finally we will now properly have our form data and we can go ahead and do await db. update uh DB grab you. update and we're going to to update the uh profile table we going to go ahead and set the um first name last name and the email beautiful and then we're going to do where EQ profile table. ID is equal to the user profile. ID and now with all that out of the way we can just return success is equal to true and then now we need to go ahead and hook this up client side so I'm going to go back down here here to my client and like I said we're doing this kind of weird we don't need to do all this Progressive enhancement we can just submit the form and have it work but I want to get a little fancy here so I'm going to go down here into my form action we're going to add in a method equals post we're going to delete this action right here we're going to go ahead and do a use enhance directive here now we're going to get a little Fancy with this so we're going to say we're going to grab form data out of this we're going to go ahead and do this so the first thing we're going to go ahead and do is we're going to set all of our state variables in our form data because if you look right here we don't have any any names on these inputs so they won't be properly bound here and again you can just give this like a name of what you want back there and have that work but again I'm just showing you the progressive enhancement so we're going to do form data. set first name last name email then we're going to go ahead down here and we're going to do return and we return a call back function here which will happen all of this up here happens before submit all of this down here happens after submit so I'm going to go ahead and say um result then I'm going to say if result. success do uh type equals success we're going to go ahead down here and say um uh we're going to want to invalidate our homepage and we're going to want to add an alert um updated and then otherwise um else we want to go ahead and do alert error so now with all of that nonsense out of the way I think we should be able to update our profile I don't know why that got imported here let's go back to our site here I'm going to go ahead and refresh everything here go ahead and fill in my name go ahead and hit update it'll say updated if I refresh the page this will all be correct and if I go back into my terminal here we do subase status we go into my um Studio URL I open this up I open up my table editor I open up my profile you can see we are now we have a functional app we can update this as much as we want can go back in here um we'll do a bun run Dev go ahead and refresh this here um we're going to go ahead and change this my full name uh update this go back to this guy here and it will be properly updated so now we have the makings of a full app here you can imagine how you could expand this to build something real um I think before we I want to go ahead and create a sign out button because I think that's just a good thing for you guys to see so I'm going to go ahead down here and add in a new button it's going to bef equals off logout I'm just going to say log out we're going to go ahead in here to our off directory we're going to add a log out right here going to add a Plus server. Ts do export const get we're going to do this is going to be async we're going to go ahead and do this um we also want to grab our locals and specifically superbase and we just wanted to go ahead and do await super base. off. signout uh and then we want to redirect 307 to the homepage and just like that we can go ahead and hit log out we'll come back to our homepage it'll say we're not logged in go ahead log into the site sign in with GitHub and now just like that we now have a functional apps so I know this has been a very long and kind of crazy tutorial but let's get this in production and make it complete I'm going to go into um GitHub here uh I'm going to go to my profile I'm going to go ahead to my repos I'm going to create a new repo I'm going to call this um superbase spelt kit 2024 tutorial um this is this is this will be the public one that will be available at the end of this so um a basic demo showing of spel Kit plus super base and in 2024 this will probably change at some point but for now this is fine so I'm going to leave all this blank because I like an empty repo go ahead create the repository we're going to go ahead down here the only command I need is this one so I'm going to copy this right here go ahead in here and I'm going to do get anit go ahead and do get add- a get commit - M created project we go ahead and paste that in here we're going to go ahead and say I already did everything right yep and we're going to go ahead and say get push oh yeah and we need to go ahead and actually do setup stream origin main now if we go ahead and do this and refresh back here zoom out to normal we have our full little project so this is all done and ready here now let's go head and deploy this we're going to start the deployment process in subase because that's an easier place to do it so we're going to go to subase I'm going to go to my dashboard I have a bunch of stuff in here um you can do this for free completely I have to do it because I have to pay here because I have so many different projects using this for Insider is for weights AI for a bunch of different stuff so I'm going to go ahead and create a new project in um the we'll do it in this org um and do a micro instance we will say um super base spelt kit tutorial we're going to go ahead and generate a password Here uh this instance will be deleted by the time you see it so it doesn't matter here going to do us East because I'm on the East Coast copy this password over here I'm going to in my do EnV I like to just store it in here just to know and just say prod pass equals this because I want to keep record of that go ahead and create my new project and once we've created this we can go ahead and get ready to start doing the next next thing so I'm going to go up here to the URL and I want to grab this piece right here it'll look like a bunch of random letters and numbers so I'm going to grab this right here I'm going to go back into my terminal I'm going to do superbase Bas link-- project ref and that's then I'm going to paste in that okay awesome so finally once you get the green light here we're going to go back into our terminal we're going to actually fire this command uh I'm going to paste in my database password grab that back from here paste that in there and now what we can do is we can do subase DB push going to go ahead and push I'm going to say yes and now that we've done this I'm going to go back over to my table editor and we have our profile table in production so let's go ahead back to our git repo here so I'm going to go back to the um GitHub we have this guy right here and now we're going to go ahead and deploy this web app you can deploy this wherever you want I'm going to do it on versel because that's the easiest place to do it so we're going to go to versel I'm going to go to my just my profile here and go ahead and create a new project I'm going to import this from the spaly 2024 tutorial we're going to go ahead and the framework preset should be should be spell kit I believe um rout directories here the output directory uh this is all correct big ones here are going to be the environment variables so if you remember over here we have a couple different things we have our um database URL public superbase URL superbase andon key and these two we don't actually need to include these two in our superb in our first cell project we just need these so the first one I'm going to get is going to be the database uh URL we're going to go back into the project we're going to go down into project settings we're going to go into database I'm going to copy this URI right here to jump back over here paste it in and then we need to change the your password field right here we need to change this to be the prod pass so we're going to paste prod pass in here we're going to add that in next thing we're going to go ahead and grab is going to be our API info so my project URL is going to be this so I'm going to say um what did I call it it's a public superbase URL it's going to be this and then we're going to say our Anon key we're just going to copy paste that in here jump back here copy this Anon key into our project add that in and that's everything we need so we should be able to go in here now and just hit deploy um oh God why is it it does this every once in a while I've SE I've seen this problem before yeah every once in a while versell does that I don't really know why they do that but they do do that sometimes um so we're just going to go ahead and into the package.json I'm going to set this to be02 we're going to go ahead and do get add- a get commit DMV and then we're just going to push this up and then if you get this error this is usually how you fix it we're going to refresh it here we're going to check on our deployments and we'll get our first production deployment and again I don't know why it does that sometimes sometimes it'll just get that weird git error it should have fired initially but if it didn't just do this so we'll give it a second here it needs to go ahead and run a bunch of stuff it'll run bun install run all of our vet build stuff Basics felt kit stuff here and in a moment we should have a project and once we have that project we need to do the last step which is going to be setting up our new GitHub instance so I'm actually going to go back to GitHub and get that started so we're going to go back into GitHub I'm going to go back into my um back into my settings I'm going to go down here into my developer settings I'm going to go into ooth Apps we're going to create yet another one we're going to call this um super base uh tutorial live we're going to set the homepage URL to um we don't know what that will be yet but the call back URL we're going to jump back to our super base uh console here jump back to dashboard jump into superbase F tutorial jump into project settings and actually we're going to jump into authentication here we're going to go into providers we're going to go down here into email and we're going to disable it because I don't want email we're going to save that um we're going to go down here into GitHub we're going to go ahead and enable it we're going to copy this call back URL jump back to GitHub paste it in here we're going to jump uh we're going to jump over to versel we should have our new URL here so we view Yep this is working correctly uh open this in full screen I'm going to grab this URL here we're going to jump all the way back to our uh GitHub here paste that URL in we're going to register our application I'm going to copy my I'm going to copy my client secret we are going to uh paste that in here and we're going to grab our client secret here generate it copy we're going to paste it we're going to save it I don't want to autofill that and just like that we should now have a GitHub provider enabled here and with all of that in place hopefully we go back to our live little GitHub site I hit login site I go to sign in with GitHub I want to authorize this yes I'm going to go ahead and do that um oh one more thing I forgot to do here we want to go back into our um want to go back here to our tutorial app thing we want to grab our URL here we want to go back into our superbase console um yeah we'll go into our superbase console into authentication into uh providers uh actually into URL configuration we want to paste in our URL get rid of the slash save it and now hopefully we can go back into our project log into the site sign in with GitHub and now we are logged in and we have our app I'm going to go ahead and fill in my name update this updated we're going to log out I'm going to go back into my subase console into my table editor view my profiles and it's working so just like that we have built a full stat spell kit superbase production application in 2024 I know that this was kind of a crazy tutorial and we went through a lot of stuff like I said link down below will be the full source code for this that repo I just published you can go through and check everything uh if you guys have any ideas on how to improve this and update this definitely leave them down below would love to hear from you guys and uh yeah I know this has been chaos but if you enjoyed make sure you like And subscribe and thank you for watching
Info
Channel: Ben Davis (Davis Media)
Views: 6,714
Rating: undefined out of 5
Keywords:
Id: lEWghUOta-4
Channel Id: undefined
Length: 59min 21sec (3561 seconds)
Published: Sat Jun 22 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.