A second version of this course released using Next 13+, but this course is great if you want to see another example fullstack project. We now recommend you take the Build a Fullstack App with Next.js, v2 course.
Transcript from the "Auth Pages" Lesson
[00:00:00]
>> The next thing we wanna do is start working on the Auth Pages. And for that, like I said, a sign in and a signup form is mostly the same just like the sign in and the signup API route were mostly the same. So, because of that, we're just gonna create a component that just toggles what mode you're in and it literally knows what to do.
[00:00:19] So, I'm gonna go to components. We'll make a new component here. I'm gonna call this authForm.tsx. And we're gonna do all the stuff in here. So what we're gonna do is we're gonna import some of our UI stuff from chakra. So let's say @chakra, layouts and we're gonna need some box stuff.
[00:00:36] I think we're gonna do some flex stuff. You haven't used flex yet, but it's literally just like a flex box div which is really cool. You could just use box and add the Flex Properties yourself but the flex component already does that. We're gonna need the input and we're gonna need the button or actually I think input button.
[00:00:55] I think these come from react actually, I would love to react there we go, okay. So we got that, we're also gonna need the router because after someone signs in we wanna route them to the home page. So we're gonna get access to the router. Up until this point we haven't had to touch a router because next year's handles the routing for us based off the folder structure the file naming.
[00:01:18] But you could actually access the router to do programmatic routing and the way you can do that is getting the use router from next router like that. So we get this use router hook. Well do that. The other thing that we wanna get from this other package is called SWR.
[00:01:39] Which stands for still while revalidate. This is also from verse L or next JS. So we're gonna do something called useSWRConfig. This package is actually really cool, it's probably one of the coolest innovations I've seen in front end development and while there's tons of other packages like it.
[00:01:59] But basically, what it does is it handles your data fetching very nicely. It'll handle caching, it'll handle optimistic updates. It'll even handle refetching and revalidating the cache for you based off different scenarios. If you're on your computer and you focus off your browser, but then you come back to your browser, it'll refetch, it'll do different things like that.
[00:02:22] It's actually really cool. And there's other ones like it, but SWR, was the one that was made by the next JS team, so we're gonna use that one. But there's another one called react query that I think might be a little, I wouldn't say better, but it has like, more options to it.
[00:02:36] Whereas SWR is just like, more bare bones, more flexible. So, try it out which one you like. We're gonna use SWR. And they useSWRConfig is gonna be a hook that we can use to basically update the local cache of this application. So if you ever use something redux, if you ever use Apollo, you have the ability to do a mutation and then get that data back, and update the local cache with the data that you got.
[00:03:01] That's basically what we're going to be doing. And this will like propagates across the whole app or anything that's listening for that data. And then the last thing we're gonna do is import our auth mutation. All right, so now we're gonna make our AuthForm, like so. And so I'm gonna exports default AuthForm.
[00:03:28] And then we can basically this all form like I said it's just gonna take in a mode and that's gonna be a string whether it's sign in or sign up that's it. It's just gonna take a mode. And if you are inter TypeScript when you wanna know how to type check, a functional component and react.
[00:03:45] There's so many ways you can do it. I see people like they'll add, like just a type here, just like you would in regular TypeScript. But if you do it this way, and you add the FC type here, you can actually type in a generic and then you could do something like this.
[00:04:03] And then now this will be type checked and then when you're in your jsx you'll see the type check over all the props and stuff like that. So this is how you would probably type check it. I'll leave if people want it but again it's not necessary if you don't If we're not doing TypeScript things.
[00:04:20] It's not gonna change the behavior application. TypeScript doesn't change how your code runs it's for build time and deaf time it's not for runtime. It all gets taken away obviously the browser doesn't understand TypeScript so it's not gonna change the behavior of your code it's just for a better developer experience.
[00:04:35] Okay so we got off form next thing we can do is set up some states to keep track of in this form, so we got to keep track of the email the password we probably wanna keep track of if we're loading or not. So we can show some type of loading indicator and then yeah let's keep us set up those states so I'll say email, set email.
[00:04:58] And that'll be useState from reacts and we're gonna to set that to be string, we gonna to copy that do the same thing for password. I'll be an empty string and then I'm gonna do the same thing for, is loading. So are we loading? Set is loading, And that will default to false and not empty string.
[00:05:32] Okay, so we got that, and then we'll get the router, so we'll say router equals use router, there we go. So we got all of our variables for now and then the next thing we wanna do is start working on some of this JSX. So what we'll do is we'll return a box, which again is basically a div that we can style.
[00:05:57] We want this to be full page so we'll say height of 100 view height with of 100 view with banana. I don't know why I put O, there we go. So we got that going and then we're gonna make this dark sorta bit of background of black like that.
[00:06:22] And then what we're gonna do is I'm basically just gonna put a form right in the middle the page. A square that has an email and a password button. So it's very basic, very simple. I want it centered. So I'm gonna use a Flexbox for that. So I'm gonna say flex.
[00:06:37] And then for that I'm going to put justify=center and align=center. Both of these are shortcuts for justify content and align items. You can also type that out if you want to, but we get that for free with this flex thing. And then I'm gonna give it a height of let's say 100 pixels maybe, so we'll do that and then what I'm gonna do is I'm just gonna put the word hello here so we can check it out.
[00:07:12] And then after this, I'm gonna make another flex. For this, it's pretty much going to be the same thing except it needs to account for this Flexbox that's on top of it, which is gonna be like a top little nav bar, all right? So we're gonna count for that, which is 100 pixels high.
[00:07:32] So we're just gonna copy just to find the center. Put that in the middle as well. Oops. And then for the height on this, we're just going to say, you're going to be calc, 100 view height, minus 100 pixels. So account for that. And then inside of here we'll just put the word form like that.
[00:08:00] And I guess you probably won't see it until I change the color of this assumption change the color white right click so we can actually see it. The background is black. Okay, so we have that we'll come back obviously finishes but you know my style to just do like a little bit of a component, put it on the page and make sure it's there so we can actually see it and then we'll develop it as we go.
[00:08:19] So, we got to authForm. That means now we have to go back to our pages and we gonna make two pages. Be careful not to make these pages inside the API, because then that would make API route, which we already have for sign up and sign in. So, make sure you got an API folder but on the root of the pages folder, we're gonna make two new ones called signin.tsx and signup.tsx.
[00:08:46] And these should be pretty simple because the Authform's doing the heavy lifting. So for sign in, all we have to do is just import the all form like, so, and then we can make a sign up function. And we're just gonna export default the sign up function and then all we're gonna do is just return the AuthForm, with the mode of sign up like that.
[00:09:16] And that's all we have to do because it's literally the same thing. So I'm gonna copy this and put this in sign in, and change the mode to sign in, and then obviously change the name from sign up to sign it on the component. So pretty straightforward. Now I'm gonna check this out, see what it looks like.
[00:09:40] So I'm gonna start my server. Up here run dev. I think I still have it open yep there we go. So here we go now I'm gonna go to slash sign in and so we got a couple things going on. Anybody wanna tell me the first issue that we see?
[00:10:07] Yes
>> There's not a button to get to this.
>> Yeah, there's not a button to get to this. So yeah, you can go to the other type it in. That's obviously a big problem. What's another problem as far as UI?
>> Looks like it's actually centered.
>> Yeah, it's not centered.
[00:10:24] Why is it not centered? What's on the left side? The sidebar? Yeah. Like, why would we show the sidebar for not signed in yet? Right? That's because we have this sidebar layout and this player layout for the whole app, even for the sign in pages. So we need to find a way to opt out of this layout.
[00:10:44] For the sign in and a sign up pages, that's the problem that we're having right now. But if we go back and look at our code_app.tsx, this layout wraps every single page. So how do we go about making sure we don't actually have that. And this is where I was saying this is why it's pretty interesting with Next.js.
[00:11:06] So, earlier I said the way you could get around this, is instead of wrapping the layout inside of the _app.tsx, you could have just done it on every single page individually. I could wrap the layout here, I could wrap the layout here, if I wanted to. I can opt in versus having to opt out, but the problem with that is that layout will get refreshed every time you change pages and the state pretty much gets refreshed.
[00:11:30] So a music playing at the bottom would restart every single time, so we couldn't have done that. So we had to move it to the app. But now the problem is, everything in the app has this layout. So to get around that, what we'll do is, we'll go back to our pages sign in and sign up, and we'll add a little property on it.
[00:11:46] So I'll say sign in, and then what I'll say, and we can add whatever we want. I'll just say authPage = true. So obviously, this is an authPage, signing out all pages true on the component, then I'll do the same thing, I'll sign up. I'll say, signup.authPage is also true.
[00:12:11] And now that I have that when I go back into my app.tsx, I can actually look at that property to see if it exists. And if it does, I can do a conditional on it. So instead of doing a layout here, what I'll do, is I'll say, components.authPage.
[00:12:29] Is this an authPage component? If so, then I only want to put the component in here like that. That's it. If it's not, then I still wanna wrap this inside of a layout. Like this. So now this is saying, yes if this is a component with the authPage property, do not wrap it in the layout.
[00:13:02] If it doesn't have the authPage property, it should be protected. It should be in a dashboard or should have the player layout There's other ways I've seen people do this, they will sometimes add the component itself as a property to that or they'll add the layout as a property to the component.
[00:13:23] Haven't tested that to see if it would actually refresh the state or not. But I know by keeping this player layout in the DOM, it'll be cached and it won't reload, and therefore we won't have song stopping every time. So now if we go back and refresh the site, and you can see that layout went away, and I always have a full page form here without that layout.
[00:13:47] But then if we go back to the homepage we should have that layout.
>> So normally things would be hot reloading, is the refresh necessary because it's at that initial component entry level?
>> Yeah first of all hot reloading isn't always, it doesn't always do his job. And secondly I'm also opting out of Next.js new build system which uses rust now actually and it has a completely different like hot reloading and building is supposedly really cool.
[00:14:21] But we opted out of it by adding this babelrc file, because we actually need a plugin that hasn't been converted over to rust yet. So there should be, there's probably issues there as well, and then lastly, yes, there is a caching issue sometimes where you're like on the root.
[00:14:35] So for any one of those reasons, it probably did not refresh your cache. Yeah, hot reloading is great when it works. But sometimes, when you expect it to work, and then it doesn't and you'd to spend three hours trying to debug and you realize it was just like cached, my goodness, I can't tell you how many times.
[00:14:56] I'm just gonna have it now just keeping this open, right clicking this, and then Empty Cache and Hard Reload every single time now. Because that's the only thing that fixes it sometimes. It's even stopping the server and turn it back on doesn't fix it. You just gotta clear everything, so pretty terrible sometimes.
[00:15:14] And that's nothing on Next.js, that's just the technology of hard reloading.