Build a custom login page for your SaaS app with Next.js, Tailwind CSS, and Next Auth (App Dir)!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we're going to build a custom login page that you can use to log in with next auth and the credential provider next auth ships with a very basic login page that you can use for quick prototyping but you really want to build something custom that matches your branding for when you ship to production we're going to build this login page with the best Technologies next JS tailwind typescript and of course all in the app directory hi I'm Ethan a principal software engineer who's been building and shipping code in the cloud for over a decade I sold my previous SAS company in 2020 and now I'm helping people like you build yours let's get started I'm picking up where my previous video left off you've built a great custom register page and we added in some custom components here we have a custom input as well as the password input we built a custom button and then we styled the entire thing with Tailwind now of course once you create your account you're going to go to the sign in page here's an example of creating your account and then it kicks you out to this you want your login page to match the branding you've been so hard developing really we want this UI to match and mimic the UI of the registration page so let's go ahead and do that jumping into the code here we have most of our content in the app directory we also have a components directory where we added in some components to build out that custom registration page components like the button input and a label we also added alert that will show the error and warning if something goes wrong during the process but now we want to add a custom login page this is going to follow a very similar approach to the registration page with a couple of minor differences let's go ahead and create the login page and then add in some basic content to get started we'll just copy what we have in the registration page remove the form and change the call to action save it and let's take a look by building on top of the components and the designs that we've already created you're able to rapidly prototype and ship this is the power of code it compounds on each other this is why making SAS applications is so powerful every feature you deliver makes it easier to deliver the next feature so with all that said let's go ahead and build the form part of this and then wire it up to next auth and now we can test all right the form is hooked up correctly now we just need to prevent the default action and then cyan let's go ahead and test and you can see here that we successfully logged in because this is the session information that was returned in the session request of course after they log in it would be nice to redirect them to either the page they were going to or a default like dashboard page and there you have it you've successfully implemented in record time probably a custom login page using next auth and the credential provider of course we're missing a few things here to really round this out one problem with this is that the sign in action doesn't know about the login page we have to add the login page to the next auth configuration so it knows where to send a user if they try to get to something that's protected jump to your API next auth configuration and here there is a Pages key which accepts a sign in page a sign out page an error page new user etc etc will you sign in here and now next off knows where to send a user if they try to access your application and they don't have permission or they aren't signed in we can test now by going back to the home screen and clicking sign in which correctly sends us to our new login page the other thing that nextdoc does is it adds a callback URL into the query parameters and this is saying where you should go after you sign in now for us here this is just the root home page but you'll notice because we hard coded it after you log in you always go to the dashboard so here in our form instead of hard coding it you should read that query parameter and if it doesn't exist then you can send them to a default location because we're doing this in the app directory you're not using the old router hook instead you're using the new hooks which break apart the router functionality so we're going to use use search params as a client hook because this is in our form which is a client component and we're going to use this to read out the search parameter and use it perfect now we'll use the Callback URL if it's present and if it's not present will default to dashboard let's go ahead and test so if we just click sign in it's going to have the Callback URL which takes us back to the root and then upon signing in it takes us back to the root so you can see how it read out that callback URL and used that instead of the default dashboard the last thing to handle is errors what happens if the user signs in and their password wasn't correct we should let them know with a nice error message with a custom login page there are two different ways to handle errors when a user tries to log in the first is if you're using the default signed in method and the sign-in method is going to redirect the user upon success then you're going to have to read out the query parameter in the URL upon failure the other way would be if you do the redirect yourself and you tell next off to not redirect the user then you can just get the promise that sign-in returns and use that let's go ahead and explore both ways to do that so you get a feel for it the first way as an example if you sign in with an incorrect password is the login page is going to reload because they've been redirected back to the login page upon failure here's the Callback URL and now there's an error credential sign in query parameter that has been added so if you read that out we can display an error message to the user here instead of setting the error using State we're just going to get the error key if there is an error key we're going to assume you have some sort of bad credentials otherwise we'll set no error now because we have this error key it's going to say oh hey look you don't have valid credentials sorry about that now this is going to be the case no matter what the error key is so you might want to read out the specific value and change the error message depending on what the error was now this might not be the exact way you want to handle it the page always is going to refresh if the user had some sort of error which isn't the best experience we're building a single page application right with nexjs we don't have to refresh the page so instead you can handle the redirect yourself if the login goes okay and if it doesn't the promise that is returned will have some sort of error information so let's go ahead and change the redirect options and switch around how we're handling these errors so now we're setting redirect to false which means we have to handle the redirect ourselves and then we can check if the sign in was okay and if it was we'll go ahead and push the user to where they wanted to go and if it wasn't and if it wasn't okay then we're going to go ahead and log the error or just say invalid email or password now we can test oh interesting it looks like the error is going to be present and OK will be true no matter what let's go ahead and just change lists and the error message here is not super helpful so we'll just go ahead and do that so now on bad password you get something like that which lets the user know they have an invalid email or password and of course our page is still nice and responsive using the exact same logic that we had on the create account page the one last thing I want to talk about is how to add this in to middleware in case you're protecting large parts of your application in the middleware you can say what parts of your app you want to be protected now very commonly you're going to want to say I want to protect an entire subdirectory of your application but I don't want to protect things like the login page or the register page let's go ahead and reorganize our app directory just to make this a little more clear obviously we have an API and next off itself can't be protected by middleware and we also have a dashboard let's go ahead and make a new folder this is a route grouping for auth and we'll move our register and login page into it and then we'll make a new one and then we'll make another folder let's just call it the app and we'll move the dashboard into that so now we have our authentication group we have an app Group we have an API route and we have our home page now what we want to protect is we want to protect basically most of these but not all of them and to do this we're going to change the middleware configuration so instead of just saying dashboard which is only protecting one page we're going to flip it on its head start out the root and then anything that does not start with register API or login protect so this is going to protect everything like dashboard or any paths under root or anything you're basically white listing the URLs here now remember we added an auth folder but we're not referencing off in the middleware this is what the URL structure looks like not what your folder structure looks like if you need more advanced configuration here instead of just exporting this configuration you can export a function and then tap into that and now with the saved if you go to the login page you can get to it and it's not protected and if you try and go to the dashboard page the dashboard is not a part of this so it should be protected and then it sends you to the login page and of course if you want to create an account the register page is also unprotected so there you have it you've now built a totally custom login page that matches your custom registration page with this Foundation you have all your authentication needs handled end to end I can't wait to see what you're going to build with it until next time happy coding
Info
Channel: Build SaaS with Ethan
Views: 11,495
Rating: undefined out of 5
Keywords: next, nextjs, next.js, react, next auth, next-auth, next-auth.js, auth.js, tailwind, tailwindcss, tailwind css, prisma, postgres, software, coding, software engineering, login, login page
Id: cm-7RmD8yKQ
Channel Id: undefined
Length: 16min 17sec (977 seconds)
Published: Thu Mar 23 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.