Next.js 14 Authentication Tutorial (Super EASY!)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
it's no secret you can't build a real application without having authentication with nextjs specifically this becomes a little tricky considering you can run code on the front end and the back end having worked at an authentication company myself I actually know just how difficult it is to do that without finding the right tools so let's see how to add authentication to a next js14 application using Clerk and Zeta and at the end I'll show you one common mistake I often see and how to avoid it all right let's start by creating a brand new nextjs project so we'll actually start completely from scratch so on the next documentation we have the MPX uh create next app command and we'll do at latest which will give us a version in this case 14.01 we'll say yes let's install and we'll call this uh next off demo and in this case I am going to use typescript uh by default that's what I do I also use es lent and Tailwind CSS because why not we use the source directory that means all of our kind of code that we write is going to be inside of a source directory which is nice and we'll also use the app router which has been stable now for a while and it's kind of the recommended way as you can see here to build nextjs applications going forward now I don't need to customize the default Imports or like aliases so we'll just go ahead and let this run and when this is up we'll open it up and get started all right so that just finished and I can open this in the same vs code window that I'm in by doing code dasr and then the directory that I want so this will be the next off demo and we will open this up I don't need to restart vs code right now it's already installed all of our packages so we can just run mpm run Dev um one thing I need to make sure and you will too is I'm using a version I think it's 18 or above of node so I'm going to switch to version 20 and then we'll do an npm run Dev on this just to see what we get by default so let's open up Local Host 3000 and you'll see we get a bunch of stuff in here we're basically going to rip all this stuff out uh but this is the starter application that it comes with so let's go and do a little bit of cleanup so inside of the source directory we have uh layouts and Pages directories or page files and these are the way we do the app directory uh inside of nextjs 13 to 14 and this is where we have everything kind of grouped by folders and in each folder for a route we'll have pages and layouts if we so choose so let's open up the uh page I'm going to get rid of everything inside of of Main and in this case we can just put in here in H1 to say nextjs off tutorial and we'll save that and that should get rid of kind of everything else on here and we see that show up there so that works and then inside of the layout the layout is going to be used as basically like a root layout in this case and it's going to be used by any nested directory so in this case uh we have a few class names for or we have the class names that include the uh font that we're using up here I'm going to get rid of the enter font and I just want to create something that'll give us kind of a base layout to use through the rest of the page or you rest of the pages so I'm going to give a Min height of screen to make sure this at least takes up the entire height of the screen then I'm just going to use a display of flex and then uh justify Center and items Center all right so let's just send it hor horizontally and vertically and I'm going to go back to the page I'm going to get rid of the stuff that they have on here because it's kind of doing the same thing and I just want that to be in the root layout so that we can share this and then lastly I'm going to give this some padding all right so now you see that just centered horizontally and vertically on the screen just so we can keep it all there now what we're going to want to have is a dashboard uh route where we want to gate that based on we only want to let authenticated users into the dashboard route so to create new routes in nextjs we do the uh folder structure so we create a folder called dashboard and then inside of here we'll create the page TSX file and then I've got a little snippet uh for a react functional component and I want to call this the dashboard page and then we'll just add in a little bit of text to reiterate that and then now this should be hosted as its own route so we could go from home to dashboard directly so you see that change there now one thing we might want to do is create a nav bar where we can list out the links and navigate between these Pages as we go and add our authentication so we can prove how we navigate to and front different directories now we could add this component right inside of the app directory we could also add a components directory and add things in here so it's kind of up to you how you do this I'm going to add it inside of the components directory for now but it really is up to you whatever you want to do so I've created that nav component I'm going to paste in a quick reference for this component so we don't have to build it all from scratch but we'll talk through what's here so we have a header tag we have a nav tag we have some basic Styles in here and then on the left hand side we have a link that just goes to the home page just like a basic navbar and then on the far side we're going to have a link that goes to the dashboard page so we have a link for home on the left and a link for dashboard on the right now eventually we'll put more links into this section so I actually surround that with a div but for now we can just uh save that now what we want to do is add this inside of our layout as well so inside of our layout above the children we'll want to add the nav component now one of the things we will have to move now since we're referencing our nav inside of our body is want to add an inner div to wrap the children and then add the styles for the centering of everything inside of that nested div so do class name equals add these Styles here and now we should see that we have our Navar above the main content which is down here so that looks like it works pretty well and we can test out the Navar by navigating to dashboard uh back to home Etc so you see that is going between pages and now we can start to look into how do we add authentication to to protect the individual Pages here so let's go into clerk.com and this is where uh they have a beautiful site here I think and they have a bunch of widgets built in that are really nice for adding signin you can customize it for all the different social media platforms or things that you want to allow your users to to log in with and I don't know I the site is just really nice so anyway we are going to start building for free so if you haven't signed up for a free account you'll need to do that and I'm going to go to my dashboard now I've already created one application for an example that I'm working on in the past I'm actually doing a buildin public with nextjs and Clerk and Zeta and centry and if you're interested in more learning more about that following that Journey you can subscribe to my newsletter at james.com newsletter and I'll send updates there uh but let's add an application in here and let's just call this uh nextjs test authentication and again really cool you can enable different uh ways to log in with the email address phone number usern name and then get into social providers like Google Facebook Apple Etc now they also show you it's really cool they kind of show you here uh what this widget is going to look like and they give you this widget by default uh so it's really neat you can add phone number and again they show all of that stuff so anyway uh we will just start with the popular of email address and uh Google and we'll go ahead and create this application and it'll kind of walk us through what we need to do so it's selected nextjs by default for project and we need to add environment variables for this to our application so we can go into our source code and add a EnV variable or file for our variables and we'll just copy these in so we now have those things saved and then it says we can continue in the docs to be able to set this up so let's go into the docs and the first thing as you might expect is to actually install the clerk uh nextjs package so we'll let that install run and we'll come back and check the docs says we need to set the environment keys and then we need to wrap the app in clerk provider now the really good thing about this is that clerk is already supporting the app router and the pages router for nextjs so we're fully supported here with the app router so let's go back to Let's close this one go back to the layout component and then we will wrap the HTML tag with the clerk provider so we'll surround this whole thing here and that'll give us access on the server and on the client to the user State and then be able to gate Pages based on that it's really neat the way this works so we wrap that and now we have access to all the stuff we will take advantage of in a minute the next thing we will do though is add a middleware dots file so this will go inside of the source directory in here so inside of source we will add middleware dots and it's not TSX because it's not a react component it's just typescript and basically what this is saying is this is our ability to Define middleware that then is going to gate all pages that match this format so by gate I mean you only allow users that are logged in to be able to get to this point so we don't want users to get to any pages that this matches which right now is all of them we'll talk about how to change that in a minute and I believe now if we were to run this application so if we do an npm runev and we go back to the running application it's actually going to automatically go ahead and redirect us to a login page so this just redirected us over to uh clerk so this page this login page is hosted by clerk I'll show you how to add an embedded one in a little bit but I can add my james. q. Gmail and now I'm coming back to the application and I'm actually logged in at this point although you can't really tell anything that's going on because we don't see anything different so we can do is start to kind of show and hide something in the nav bar based on whether or not we are logged in so let's open up the nav and inside of here we need to be able to check whether or not the user is actually logged in to be able to conditionally display different pages so because we're going to do that on the client we're going to need to mark this component as a client component so use client this signifies in nextjs that this will run actual JavaScript on the browser so from here we can use the use user hook this comes from clerk nextjs package and from that we can destructure the user and is loaded property so basically what happens is this JavaScript code when the page gets loaded is going to run it's going to check to see whether or not the user is authenticated if it is the user will be set if not the user will be null or undefined and then it also gives you an idea of whether or not it's finished loading checking that so you could display something else in the meantime if you wanted to so let's actually surround this part with uh some logic to check whether or not the is loaded is already true and we do have a user so if we've already loaded and we do have a user we want to display the link for the dashboard so if we go back and refresh we should see this was this is going to show dashboard notice it doesn't show immediately because it's doing that check to see if the user is authenticated so one additional thing that we might want to do is add the ability for a user to sign out now it's really cool because clerk already has this taken care of also so what I want to do is I want to wrap the link that I just created inside of a fragment in react and then what that allows me to do is add a separate uh link or an additional link inside of this so this link is actually going to be a button and this is going to come from the user button that comes from the clerk nextjs package and the fact that this has so many things already taken care of for us is really nice now one thing we do have to configure is the after sign out URL or we don't have to but we will here by default or we will here anyway and that's where we set after the user is signed out we want to redirect them the user to the homepage so let's just see what this gives us this gives us a an icon in the top right with a picture of ourselves and we can click on that and and we can manage our account and we can sign out so manage account pops up with all the account information that we can tweak and customize that's really cool and then also we have the ability to sign out from here so if we go to sign out we now see that that piece in the dashboard disappears because we're only displaying those links if the user is signed in now one additional thing you might have noticed is that it then redirected us back to the login page and that's because right now our configuration for this if we go back to the layout our conf or actually into the middleware our configuration says basically to protect every single route by default so any route that the user would go to right now would be protected which means they would have to then log in but we want to customize that to allow the user to get to the homepage without being logged in so to do this we can add a public routes property to this off middleware and we pass in an array of routes that we want to be public and so we can just add in the Slash the root page to say that will be public while the rest is not so before we log in let's just go to Local Host 3000 now this should be okay to go to which is perfect if we were to go to SL dashboard though we will now be redirected to our uh hosted sign-in page we can then sign in and then be redirected back to the application and now we see our logged in items in the Navar now one thing we may not want and you can kind of figure this out for yourself is what if the user is logged in in they try to go to the homepage well in that case we could if we wanted to actually redirect them back to the dashboard so let's go into the page the homepage so just page in the app directory and we can do some logic in here to check whether or not that user exists if they do then redirect them over to the dashboard page so we can use the off function from clerk nextjs package and from here we can grab the user ID so this is all running on the server because these pages are server components by default and then inside of here we can say if there is a user ID we want to redirect the user using the next navigation redirect function to the slash dasboard page so again we've already accessed in the nav component on the client using use user hook we've accessed the user now on the server we can use this off function to gather the user ID and then be able to do anything we want based on that so this is saying if the user does exist and they try to go to the home H page redirect them to the dashboard so if I try to go home this should now redirect me you kind of see a little flash there of going back to the dashboard cool now the next thing we might want to do is work on saving some data and for this we're going to use Zeta which is an awesome platform that I've been using in my build-in public they have ai Vector search built in they have search capabilities built in and they just have a visual dashboard for creating content so let's go ahead and sign in you can create a free account uh if you want you can see I've used many databases in here let's just create a database and let's just say that we're going to call this our test off DB so let's go ahead and create this and we'll open it and inside what you'll see is that we have the ability to create tables with a visual editor which is really really nice so I'm going to add an empty table and I'm just going to call this folders so in the dashboard that I'm working on I allow users to create folders to organize content so we'll create a users table or a folders table and then inside of here we'll create another column and then we'll have a string which is the name of the folder so not too much specific going on here just letting the user create new folders and then eventually we'll display them based on the user as well so we can mark this as unique and now we have our name property we also have our database now how do we then connect our locally running application to Zeta to be able to make all this stuff work well the cool thing thing is that Zeta has a CLI where I already have this installed but I can run the Zeta AIT function and this will connect this application to a database inside of Zeta so you can see it asks me which one I'm working with I can go to the test off DB say yes that's the one uh we want to make sure that aemv file is added to the. get ignore yes what kind of code do we want it to generate for us this is the beauty of Zeta that it generates typescript code for us so we already have our types so in this case I'm going to choose typescript and then we can tell it to Output the code to the source SL Zeta file so it did two things it updated ourv file so EnV now this added in an API key and which branch we're working on something we won't even get into in this video but is really neat so we have our API key to be able to connect to that Zeta database from our locally running application now the other thing it did was install The Zeta client which we'll use in a minute and then lastly if we look inside of the code it created a Zeta TS file which is the the file that holds the types for our table so you can see it defines the table here our folders table and then the columns and then it does some typescript fanciness with inferring what the types are and then gives us access to that it also then allows us to get a instance of the client by calling this get Zeta client function and we can use that to now be able to generate data so let's just go back into this and let's create a couple of different rows so we'll call this folder one and we'll create folder two now this is all just kind of simple dummy data but let's go into our dashboard so let's go into the dashboard and let's now use the Zeta client by calling Z get Zeta client and so we'll call this Zeta client and then from here we can use our Zeta client if we go into DB dot then we can see the tables that we have based on that typescript so folders and we we can call the G mini function because we just want to get a list of the folders that are available so we'll call this folders and this is going to uh come from awaiting the call to the database now to work with this we have to tag this as an async function and now remember these are all server components by default which means we can run a weits right inside of here and then reference our backend environment variables it's used underneath the hood with this function here but we can do all that on the server without having to worry about giv get giving up our secret credentials so this is all safe to do just like we are now we have our dashboard page I'm going to wrap this inside of an H one and then this won't look great but underneath that we can have a folders. map get a reference to each folder and then we can just add a P tag for the folder Dot and this should be map instead of maps the last thing we need to do is add the key prop and we can reference the folder. ID for the key so we should be able to save this and make sure we're running the application so rerun this with mpm runev then go and refresh then go and refresh on our page and you see we have our folder one and folder two listed for us so we're able to query all this data and be able to get back the associated data so now one thing we might want to do though is try to integrate the stuff that we're doing in Zeta with the actual authentication that's happening in clerk so how do we associate data from Zeta with our user that's saved inside of clerk well we do that using the user ID of the user so for every folder that gets created we want to attach that to a specific user ID so to demonstrate this let's create a new component for our dashboard and we can actually create this right in inside of the dashboard folder or we can call this the folder form component and let's just stub this out so we have that and I'm going to paste in some markup and this is mostly going to be a basic form so let's just take a look at what we have we have a form defined here we have a few tail one classes we have a label which is the name of the folder and then we have the input which is the actual uh input text and lastly we have our submit button now notice that I have this referencing an action function that I haven't defined yet this is going to get into server actions which we'll see in a second but that allows us to handle this form submission and actually display whatever data we want and then save the data to the database so we haven't defined this yet so let's just first Define this function so this will be an async function called create actually folder is what it should be so create folder and then this will be a function that takes in a parameter of form data which is of type form data and then we will need to do something inside of here now to make sure that we Define this to only be running on the server this function is defined with The annotation of you server so in this case from here we can just log out the form data doget and then get the folder property which is actually uh name so we're looking for the name of the folder so we can just log that out on the server so let's go ahead and save this I will actually need to add this to the dashboard page as well so on the dashboard page we'll want to display the folder form and then I'm going to add a few classes in here so I'm going to add a div with a class of MB of 10 just to give some spacing between everything and then from the H1 we'll give this a class of mb4 to give some additional spacing so we should see we have our dashboard page header we have our form with the folder name and then the submit button and then we have our list of folders that were created so we can type in here folder three and press submit and if we come back we should see this actually logged into the console that's but and this is logging to the console because this is being run on the server instead of the client so if we look inside of the browser just to confirm where this code is running we won't see any logs in here to show what we just saw on the server I'm going to zoom in a little bit to make this a little bit bigger so that's working as we expect now we want to take that from there and actually use this to be able to create a new folder inside of Zeta so we can start to reference the name so we can say cons name equals and then get the name there and then from here we can use our Zeta client so let's get the Zeta client Again by calling get Zeta client then we can use that go to DBS do and then we'll go to folders and then we'll call create and we'll pass in an object that takes a name property or has a name property now this typescript is telling us that this property is actually required and we have no guarantee that this name property exists from the form so one of the things we could do is check to see if there is no name then we could do something else and we could just return in here if there is not a name now instead of hardcoding this check in here one thing we can do and this is on the documentation for uh next year 14 is to use a package called Zod so we can install Zod and this is a validation package that we can use and we can define a schema and so we'll do this from Z doob and this Z is going to come from Zod so we'll add the import for Zod and then inside of this we will now Define the name property to be of type string with a minimum of five characters for example all right and then from there we can ingest the data from the form into this Zod schema so we can call schema. parse and then set a key to name and then a value to what comes back from that form so this should now give us the pars form or validated form or whatever we want to call it so this has a property of name and now we can get rid of our own manual check and we can now pass that object into our create so parse form and this is now validated as having a name property that is of type string so we can go from here and wait for that create to happen and now we can save and run this application again and hopefully we'll see that we're able to save data into the actual database so we'll refresh we'll type in folder three we'll submit this we don't really see anything happen here but if we go back to our Zeta table we should see now our third folder is is created so if we go back to the application and reload it now shows our new folder but we probably want that to show by default so one of the things that we can do is after this happen successfully we can call revalidate Path and that will kind of revalidate or recheck for the data for this page so if we tell this to revalidate this path and now we try this again so we type in folder of four we can now do um the revalidation and it will show up with our folder but you'll notice that this folder for say stays here so we actually want to reset the form after this is submitted now I don't know the best answer to do this but one of the answers that I found is to be able to mark this form as a used client so this is client side code and then we can add a ref to the actual form element and then be able to inside of the action go ahead and reset that form so let's just copy over a few pieces of code to be able to do this inside of here we'll annotate this with use client and then inside of the component below the create folder we can paste in this this ref and then import the use ref and we're saying the ref is going to be attached to an HTML form element which is what we've defined on here so we can set the ref to the ref that we just defined and then inside of the action we're going to Define kind of an inline function here and then inside of the inline function we're going to do two things so this is going to take in the form data and then what we're going to do is call the create folder function by passing in that same form data and then we're also going to reference our ref and then current and if there is a current then we're going to call reset on that form now one of the things that nextjs doesn't like is that it doesn't want us to define a server function inside of a client component so one of the things that we can do is we can copy and paste this and move this to the root dashboard page so we can Define this in here and then make sure we copy over our schema as well so we'll copy and paste over our schema we'll make sure to get the import for Zod we can add all missing Imports which will get the import for the revalidate path as well so we've copied this over and now we need to pass in this function into the folder form so we can pass in a property of handle create form and this will be the handle or this will be the create and this will be the create form function create folder function and I keep saying form this should be folder and then inside of our component our folder form component we now need to define a property which is handle create folder and we'll Define types for this as well so handle create folder is a function that takes in form data which is of type form data and then returns void so we have that defined now we can call the handle create folder from inside of our client component even though we defined it inside of our page component which is a server component so now hopefully this puts everything together and we can now enter in the folder five and what should happen is it should show up with folder five down here and then also reset the form so we do submit we see that this disappears up here and we also see folder five listed so now that we have all this working what we want to do is now make this connection between the user in Clerk and all the data that we store in Zeta now I kind of referenced at the beginning of this video a mistake that I often see people make and this is what's going to help address that now a clerk is built to take care of sensitive information about a user like passwords and tokens and all the private information that you want to make sure doesn't get leaked in your application so my recommendation is to let providers like clerk take care of all of that stuff and then we can use our own database for additional Association with the user or if we want to do additional properties for a user like profile information or additional things like that I think that works well to tie into a table inside of Zeta so let's start by associating all of this data with an individual user so for this we're going to need to add another property for each record for a user ID so we can add this here now the user ID for these won't be unique but we do want to make sure that it is not null so we can add a default value in here of the string null which doesn't really matter but we want to make sure that this thing is required now let's go and see what the actual user ID is for a given user so to do that we've already accessed this inside of our code so far and this is inside of the root page directory and we can just log this on the server user ID so now we can navigate back to our application and try to go to the homepage we'll be redirected to the dashboard which is fine but then if we come back in here we should see our user ID is logged out out and now we can go back into Zeta and then set the user ID for these records now I'm not going to set it for folder four and folder five because I want to show you something that's really important in a second so if we look in here we should see that we're still getting all of our folders and that's because we're not filtering our data based on the actual user ID so in the dashboard in the dashboard homepage we actually want to reference that same user ID so we can reference the same off function from Clerk xjs and then we can destructure the property of user ID that comes back from that now from there we want to actually query all of our folders based on the user ID so we can call in a filter function and then inside of this filter function we can Define what we want to filter by and we want to filter by the user ID equaling the user ID of the logged in user so we only want to get information associated with the logged in user now notice this is giving me a typescript error that's because we haven't regenerated ated our types after adding that additional property inside of Zeta so to get an updated type for our table we can run Zeta Cogen and this will regenerate all of those types and then we should have an error that goes away now now the last thing is it says that this thing can't be null but what happens is this could be null up above so really what we want to do is do a quick check to say if we don't have a user ID the user shouldn't be here anyway so we could call a redirect from next navigation and just redirect this user back to the homepage so now by the time we get to the point of trying to save a folder or query folders based on the user ID we should only get the folders that are associated with this logged in user because we know this user is logged in based on their user ID so we can save this and make sure we rerun our application and then what we'll see is when we refresh our folder page in the dashboard or the list of folders inside of the dashboard we should say that we only see folder 1 two and three so now you see we only have folders 1 two and 3 and I don't think we need to go through and test this but we could log out with this account sign in with another account associate certain data with that user and then be able to show that the different ones are only showing up for the appropriate user but the last thing we need to do is inside of our folder form now or inside of the function that we call to save that we want to make sure that we now get the user ID and attach that to the form the parse form that we add in so we can create a new variable called new record for example and we can spread in the parse form data and then we can set the user ID to be the user ID again of the logged in user now we have that referenced up there so we should be able to just pass that in as a value for our new record and then we'll save our new record into the database now this is giving a similar issue to what we had earlier where we needed to double check to see that that user ID did exist so we can just add a quick check in here to say if the user ID doesn't exist we can just just return out and move that above the creation of the new record and then pass that in to create now you could add some additional logic in here to do whatever you wanted but let's go back over to our application and let's try to add a new folder so we add folder six we should see it disappears here and then it also then redisplays inside of the browser that means if we refresh we see this showing up as well and then if we go back to Zeta we see folder six and the user ID is being set correctly so this is the key for me of integrating a an authentication platform like clerk with something like nextjs is keying off of this user ID so we can show ownership for any record inside of Zeta based on that user ID which is associated with the actual user information stored in clerk this is the key between the two now clerk also has some ability to do metadata on a user object but what happens is you have to tap into their specific API to be able to update metadata on the user that they keep track of so I think that it makes a lot more sense and we have more control of being able to add properties inside of information like this or if we create an additional user settings or user profile table inside of Zeta we would do the same thing where we key off of that user ID and we now have control over that information while leaving the security and stuff that needs to be secure stuff to clerk because they have spent lots of time and money on making sure that stuff is secure now one last thing I told you I would show you how to do is to customize the signin and login pages so right now if we try to go to the dashboard page it will force us to the login page and if we look at the URL this is actually hosted by clerk so this is a page hosted by clerk somewhere else instead of an embedded login page that we control in nextjs so let's see how to do that let's go back to the documentation and they reference building your own signup page and they even give you sign up and sign-in components that you can use yourself so what I'm going to do is actually just copy this route so let's copy the route and let's go into our app directory I'm going to create a new file and paste in that route now this looks a little odd but what I did was paste in the signup directory and then the sign up folder underneath that has the angle brackets and the dot dot dot and this basically allows this page to be dynamic and to handle any sort of additional URLs pass just sign up so we don't have to worry about that too much all we really need to do is just cop Cy the sign up component into here so we'll paste that in and then we do the same thing for the signin page so we paste in our route so let's go back to app and create a new file paste in that route again so that will create the signin component and its page so now we can paste in the code for that and again this is just using signin and sign up components from clerk now the last thing is we need to be able to tell our environment to be able to do the redirects to these Pages for sign up and sign in and then we need to handle the where do we redirect the user back to after they've signed in so let's go back into ourv and let's paste in these properties and notice that we have a reference to the signin page the sign up page and then where do we want to redirect the user to after sign in and sign up well in this case we want to re redirect the user back to the dashboard page so we can save this and hide ourv again and now I think this should be ready to go so if we go back to our application we could go to the SL signin page and this should allow us to see an embedded sign-in page uh just like we saw before but now hosted on our own nextjs application and we can start the process of handling signin redirect over to Google get redirected back to our application and now it will redirect us to the dashboard page which is exactly what we want so let's just log back out so we can see this one more time so in the signin page you also have the ability to customize this completely so you can actually go in and Target any of the classes in here any of the items in here and Target them with tail one classes to be able to style this however you want so in this case you get full ability to customize what the signin and the signup forms look like and make sure that they're on brand with your application so that is setting up authentication inside of next js14 using Clerk and Zeta and then showing the relationship between the two of how to associate data inside of Zeta with the clerk user if you're interested in learning more about all the stuff I'm working on you can sign up for my newsletter at James qq.com newww I'm going to continue to be working with NEX js14 with Zeta with clerk with centry I'm going to add in features around AI I've got a lot going on so if you want to check that out check it out at my newsletter for more updates on a regular basis I'm also planning on building a course around this over the next few months so I'll probably create a landing page for that soon and I'll let you know in the newsletter if you're there where to find it and how to sign up for that as well so anyways I hope you enjoyed the video let me know what other questions or things you'd like to see covered in nextjs with Clark with Zeta Etc in the comments below and I'll try to create some additional content to make sure to fill all those voids hope you enjoy the video and I'll catch you next time
Info
Channel: James Q Quick
Views: 60,724
Rating: undefined out of 5
Keywords: next.js, nextjs 14, nextjs auth, nextjs authentication, clerk, setup clerk with nextjs, clerk and xata, xata database, web development, authentication, authorization, nextjs app router, server-side authentication, client-side authentication, clerk auth next js, clerk auth tutorial, react authentication
Id: dHCprszrMqo
Channel Id: undefined
Length: 38min 3sec (2283 seconds)
Published: Thu Nov 09 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.