So now I want to talk about routing for a bit. For example, how did I know that this page.tsx file right here is the root and entry point of our application? How did I know that this is the file where I had to add this button in order for that to be rendered on our localhost 3000 right here. Well, it's because of two things. First is the fact that this file is inside of the app folder.
App folder is a specially reserved folder inside of Next.js which is going to be used entirely for routing. The second fact is that this file is named page.tsx. Page is a reserved file name inside of Next.js which tells the router that this is something we want to show to the client, right? In a form of a client route. What's also important is that inside of this page.tsx we must have a default export.
If we don't have a default export this is not going to be recognized as a valid page component. And one more thing if you're wondering the name of the component does not matter. So you can rename this to page for example and it's still gonna work but what does matter is that the name of this file is page.tsx. So here I've written a very quick diagram. Inside of the app folder if you see page.tsx or if you're not working with TypeScript it can be page.js or page.jsx.
So it's just the name that's important, not the extension. If you see app slash page that is the equivalent of going to localhost 3000. If it was something else like app slash foo.vsx in that case that would not work. That is not going to be a route because foo is not a reserved keyword. Now that we know that how about we create another client route.
All we have to do is create a folder and then put that reserved file name inside of it again and that's going to translate to localhost 3000 slash that folder. So let's try that out. Right now if I go ahead and go to slash folder I have a 404 error. So before we create this properly I first want to do it incorrectly so I can show you this example. So I just told you that this is going to be a valid route if we create it like this but if we try it like this first this is not gonna work so I want to do that first.
Go inside of your app folder, create a new folder and you can literally name it anything you want. I'm literally going to use folder for now and go ahead and create a new file, full.dsx. And we're gonna make it a completely proper component. So const is gonna be called folder page. Let's return a div folder page.
And we're also gonna ensure that we do an export default of that folder page. So basically we're following all the rules for a proper named route, right? But what happens if I try and refresh on localhost 3000 slash folder, I'm still getting a 404 page even though this is a completely correct code. So that's what I'm trying to tell you. Page is a reserved file name.
So whenever you want to create a client route, be that in the root of your app folder or is that going to be a sub route like slash folder it needs to be named page.tsx and it needs to have a default export. So now what I want to do is rename this from foo to page.tsx and once you save this refresh your page again and there we go I am on localhost 3000 slash folder and I'm rendering a folder page. So now we proved this concept right if it has if the folder has anything except page.vsx inside, like foo, that is not a route. But if it has page.vsx inside, then that is a valid route. And what you can do is you can also create as many additional sub routes as you want using the exact same concept.
For example inside of this folder let's create another folder called folder 2 and let's create another page.vsx and let's do one more time so folder to page and let's return a div folder to page and now what I can do is in my URL bar I can go to slash folder slash folder to and there we go now I am in folder 2 page as you can see right here so I can either go to slash folder or I can go to slash folder 2 so that's how you create nested routes. Great! Let's go ahead and let's remove this folder altogether. So just make sure you have an empty app folder and you should be getting a 404 for anything besides localhost 3000. What I want to show you now is how to create an API route.
So this is just going to be a very quick preview to show you that you can do that almost exactly the same. But instead of using page, you're going to be using route reserved file name. So let's go ahead and do that. Inside of my app folder, I'm going to create another folder and let's call this folder again but this time I'm not gonna put page inside instead I'm gonna put route.ts inside and what's important with route.ts files is that you never do a default export inside instead what you do is export function and then you're exporting the type of route which you need, be that get, post, put, options, patch. Let's do a very simple get request here and let's do return response.json boobar like this.
So let's take a look at our structure, app folder and then folder. So if I go to localhost 3000 slash folder you can see that now I no longer have that client preview. Instead, I'm returning JSON here. So I have a little extension in my browser which prettifies this JSON. You might be having something like this, for example.
But it's the same thing, right? So this is how we do API routes using a very similar method but instead of it being page.tsx it is route.ts. So route is an equivalent reserved keyword for creating API routes as page is for creating client routes. Now that you know about these two reserved keywords, route and page, I want to talk about the third one, which is layout. So we already have this layout right here and this is called a root layout.
We're not going to play around too much with that one. All that you need to understand about this one is that it is absolutely required for your project. So you can never remove this file. Layout.tsx inside of the app folder must always exist. What it serves is that it renders your actual content which is children inside of your HTML structure and your body structure.
Later we're gonna wrap this even more in maybe some providers like toasters, some queries and stuff like that. But that doesn't mean that we cannot create our own layout files. So let me just go ahead and close everything here and let me delete this folder altogether. And now I'm just going to go to slash localhost 3000 back here and let's go ahead and create another folder here and let's call it out. Now inside of it let's create another folder login and create page.vsx inside.
Let's do a very quick login page here with a div login page and make sure you add an export default. So now if I go to slash out slash login there we go I have my login page right. So now I'm going to create another one called register and inside of it create page.tsx let's go ahead and do the same thing so register page a div register page so now I can go to slash out slash login and slash out slash register like this. So what if I want to create a reusable layout which is going to reflect everything inside of this out folder. For example I want my my out routes to have a specific nav bar or a specific sidebar something like that.
But we can do that using the reserved layout file. So go inside of your out folder and create a new file layout.vsx and the moment you create this file you're going to get an error. That's because it does not find the default export inside of this layout. So let's go ahead and do that. Let's call it outlayout.
And let's just render an empty div inside. So again, make sure you do export default outlayout here. And this is my structure again. So this new layout file is inside of the out folder and as you can see now we no longer have an error but we also don't have absolutely anything rendered. Right now I am on localhost 3000 slash out slash register and this is not visible.
If I change it to slash login, it's not visible either. So what's missing here is the children. So let's go ahead and extract the children. Let's give them some types. And let's go ahead and render them inside of this div.
And now we can see our text again. So I can go to slash out slash login or slash out slash register and both of them are visible. So whenever you're working with layout files, remember it is a reserved file name, meaning that it's always gonna behave like this and you're always gonna have children in the props of a layout function. So if you're wondering how did these children come here, well very simply because that's the way Next.js works. So what did we actually achieve by doing this?
It doesn't look like we did much. Well, that's because we're not actually using this layout to do anything. So let's go ahead and do that. So I'm gonna give this div a class name alt flex, flex-col, and gap-y-for. Like that.
And then above the children I'm going to create a nav element which is going to say auth-navbar and let's give this a class name of padding-1 bg-red500 and w-full. And there we go. Now I have an auth navbar in my register page. But also if I go to slash auth slash login it's also here, right? So what I did right here is created a reusable layout which is reflecting all of my routes inside of the app folder Both my login and my register page Which don't have the navbar defined inside of them all have now bars when it's actually comes to rendering the route So that's what layouts do Layouts are very useful when you want to create a set of reusable layout elements across multiple routes.
For example, our Twitch clone is going to have an off bar and a sidebar and a layout file is exactly what we need to achieve that. So now you know how layouts work but there's one thing bothering me about this approach and that is that if I want to create a reusable layout I first have to create a folder which is going to be visible inside of my URL, right? So what if I didn't want this to be an auth prefix, right? What if I just want to go to slash login and slash register without the auth in between? Right now it looks like we cannot do both that and also have a layout file.
Well, there actually is a concept called route groups. So what I want you to do is to remove this folder. So go ahead and completely delete this and go back to localhost 3000. And what I want you to do now is instead create another folder but this time give it a name inside of parentheses, ALF, like this. And then go ahead and create another folder, login, create another folder, register And let's go ahead inside of login and create page.psx.
Let's do a very quick page here. Login page. Let's copy this and let's paste it in the register here and let's rename this to register page. The name of the component doesn't matter it just matters that you do a default export. So what we achieved now is that I can actually go to slash login and look at this it's working without the auth in between.
So I can directly go to slash register or to slash login. So by using this parentheses, you tell the router to not take this as a part of the URL. So this is only an organizational folder. And what's great about this organizational folders is that not only they are well good for organizing stuff when you don't want this login and register to just be randomly laying around in your app folder, but rather be structured together like this, they can also hold layouts. So let's do that again.
Let's create layout.dsx. Let's go ahead and render out layout here. Let's render a div. Let's extract our children here. Let's give them a type.
And render the children. And there we go. So now our login and register pages are still working and we have a layout. And we can do this exact same thing. Last name flex flex call gap y4 a nav saying out nav last name to the nav to be bg-red-500 and w-full.
We can just do this for now. And try it again. So go to slash register and go to slash login. So both of them are now sharing the same layout and we are no longer having that little problem where we had auth as a part of our URL. So that's what route groups are useful for.
Great, so this is what I wanted you to understand about routing inside of Next.js. If you're still having problems putting this inside of your mental map, I wrote this little diagram which might or might not help you. So when you have a layout inside of a folder, it's going to reflect that to every route inside of that folder. So this is our first example right where we had the actual auth inside of our URL. We now change that to be like this right and then we no longer had auth inside of our URL instead all of that just became slash login and slash register.
So basically layout encapsulates all of the routes inside of that folder and what's cool about layout is that it does not re-render every time you change the route, right? So that's why layouts are useful Because once they are loaded and rendered, they're not going to be triggered every single time you change one of the matching folders inside. They're going to stay rendered. And now what I want to talk about is types of routes, sorry types of components and files that exist inside of the app folder. So let's go ahead and remove this as well.
Let's go back to localhost 3000 and let's go ahead and create just a test folder with a very simple page.tsx inside. So const testPage. Let's return a div, helloTestPage. And let's go ahead and go to slash test. And yep, I forgot to do export default test page.
There we go, hello test page. And now this seems like a normal React component, right? Well, let's go ahead and try and do something. Let's go ahead and give this an onClick and let's go ahead and do const onClick here and let's console.log something and let's pass this onClick to this function here. What happens here?
We have an error. It says that we cannot do this. It says if you need interactivity, consider converting part of this to a client component. So what does this mean? What's important for you to understand is that Next.js introduces a new concept of components called server components.
And every component that you create inside of the app folder is a server component by default. Server components are useful for a lot of things but they differ from client components when it comes to interactivity. So server components are rendered on the server, they are extremely good for SEO, they also have the ability to immediately connect to the database. So if we want to do what we could do here is literally do await our database then some model that we have like users find many. We could literally do that inside of this server component.
So that's what they are extremely useful for. But they are not good when it comes to interactivity. As you can see here, we have an error. So how do we turn this into a normal component? Very easily by adding UseClient at the top.
Once you do that, let me go ahead and open my browser here and I click on this div. There we go. You can see the console logs in here rendering something and it is increasing every time I click. But if I remove useClient we get that error back again. That's because server components by itself cannot have any interactivity between them.
So I just want to clear that up because you're going to see me writing useClient a lot. So every time I'm writing useClient it means that I'm converting a server component into a client component. There isn't any need to explain client components because they are the normal components that you are used to, right? They're function components like normal components inside of standalone react applications. But when working with Next.js, all components are server components by default and you need to manually tell it okay for this one I want it to be a client component.
It's also important to understand that there is nothing wrong with having a lot of client components so that's completely okay. So now let's go ahead and clear this up. Let's bring this back to normal and we can in fact just remove this test. We no longer need it. So just leave it back at the localhost of 3000.
And here I have one last diagram for you to understand the difference between server components and client components. So server components are backend behavior. They have database access, server cache, they are available for streaming, partial rendering, they are good for SEO, and they are extremely good for initial page load. Whereas client components are your usual components that you're familiar with and they represent front-end behavior. They have access to useEffect, useState, useCallback, useMemo, all of that stuff that you are used to.
Great! So now that you know the basics of routing, of creating named routes, of creating API routes, of creating route groups, you're finally ready to start creating a structure here which we're gonna reuse to create our authentication.