Next.js 13 Tutorial | Routing & Navigation β
Next.js 13 Beginner's GuideVintageπ
2023-05-05
Tutorial Overview β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LEARNING PATH β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β LEARN β
β βββββ β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Watch βββββΊβ Understand βββββΊβ Follow β β
β β Tutorial β β Concepts β β Along β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β β
β βΌ β
β PRACTICE β
β ββββββββ β
β βββββββββββββββ βββββββββββββββ β
β β Try It βββββΊβ Experiment β β
β β Yourself β β & Adapt β β
β βββββββββββββββ βββββββββββββββ β
β β β
β βΌ β
β MASTER β
β ββββββ β
β βββββββββββββββ βββββββββββββββ β
β β Build βββββΊβ Share & β β
β β Your Own β β Iterate β β
β βββββββββββββββ βββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββKey Takeaways β
- Core concepts explained
- Step-by-step implementation
- Practical examples
Transcript β
[00:00] hello and welcome back in today's video we'll have a look at routing and navigation in x13 in next 13 you can Define pages also known as routes within the app folder if we expand the app folder we can see a few files in this folder for instance we can see a folder called API we can see a globals.css file for the Styles but pay special attention to these two files layout and page page and layout are specially reserved names
[00:32] in next 13. if we open up the page file we can see some code that looks very similar to HTML but in the react World this is actually called jsx but it very much behaves exactly the same as HTML and this is where we can Define the content of the pages of our application this page file in the app directory is also known as the root page or the home page of our application we can see this fight in action by running the dev
[01:02] server so I'll actually open up the integrated terminal and from here we can run npm run Dev this will start our development server on localized 3000 so if I click on localized 3000 we can see our application running in the browser and the content in this root page file is reflected on this main page over here I'm just going to clean up this page for our demo purposes I'm going to remove these Imports I'm also going to replace this main tag in all of this content
[01:34] with my own main tag and we'll add a header with some text and I'll just call this home page after saving this we should see the changes reflected immediately in the browser so let's save this and that worked this does look a little bit messy due to the styling so let's remove all of the styling from the project so what I'll do is I'll go to the globals.css file and I'm just going to delete everything in this file and save the changes let's refresh this we can also go ahead and delete the
[02:05] page.module.css file we'll cover styling in another video in order to add another page to our project we need to define a new route we can create new routes by using folders within our app directory we can create a new folder and let's call it blog note that this folder blog is also known as a route segment in xjs if we go to this folder or in the URL if we go to localize 3000 slash blog we
[02:36] will get a 404 message because we haven't created the page content yet but just take note that the folder that we created here or the segment also has a one-to-one relationship with the segment in the URL itself so let's create the page for this segment within the blog folder we can create a new file and we will call this file page.js within page.js we need to export a react component basically all this means is we
[03:06] need to create a function which we export as a default function so I will write export default function and I will call this Blog Page you can call this whatever you want it's really up to you but I will call Mine Block page with parentheses followed by curly braces within this function we need to return some jsx code or HTML code for this I'll simply return an H1 tag with a text Blog
[03:37] Page let's save this and let's refresh this page and there you go we are no longer receiving the 404 error but instead we're getting this text over here let's create another route called dashboard and within dashboard is create a page file within page we need to export a react component we'll give it a name like Dash support page and we can test this out by going to localhost 3000 slash dashboard and that gives us the
[04:08] dashboard page text just a note on the naming Convention of these files after setting up next.js the project came standard with some of these files and the naming convention that was used was page.js of course you could rename this file and if you were using typescript you could use page.ts instead another convention which I prefer is dot jsx the difference between the two from what I can tell is if I change this file back the dot JS for a second if I wanted to
[04:41] use emit to quickly generate HTML code I should be able to type something like Dev and then hit tab to generate this Dev element automatically but as you can see there's no Auto completion or any image Behavior at the moment but if I rename this file to Dot jsx and I try this again we now get this Behavior this is very helpful for quickly generating HTML tags or generating sample text using low rim
[05:12] so I'm actually going to go ahead and rename all of these files to dot jsx so let's talk about nested routes let's say we wanted a nested route within the dashboard route so in the browser it would look something like this local OS 3000 slash dashboard and maybe within dashboard we have another route called settings so in order to create nested routes we can go to our dashboard route within the dashboard route we'll simply create a new folder with the name of the
[05:44] new segment which we will call settings and within the settings route we need to create a new file called page.jsx within the space file we'll export the new react component which we will call settings page let's return an H1 tag with a text settings page and let's save that I'm going to refresh the browser and after refreshing the browser we can see that our settings page is working this just a little side note routes like this they do not have any
[06:16] nested routes within it is called a leaf segment in next 13. let's create another nested route in dashboard So within the dashboard folder I'll create another folder called account within account we need to create our page file and we need to export a react component which I will call account page within account page let's return an H1 tag with the text account page let's test it out in the browser I'll just reply settings with
[06:47] account and that's working let's talk about layouts I'm actually going to go back to the home page and within our main app directory we can see this file called layout or jsx in the layout file you can define an HTML template or structure which will be inherited by all routes within this folder this layout will be applied to the page that is at the same level of this layout file as well as all the nested routes within this directory let's demonstrate this a
[07:18] practical use guys for this would be to include something like the navigation bar or the foot there or anything else that is generic for all the pages within this project let's have a look at this within the layout file we can see that the layout file is inheriting all the global Styles which will be applied to the entire project this also includes a font and it's also exporting this metadata object which we'll look at a bit later but the layout fall like any other component within this project exports I react components called root
[07:50] layout and this function takes in a property called children and this thing returns any HTML which makes up the layout of this project children represents all the contents of the files within the project so what layout is doing is it is defining an HTML structure for our project and it is then wrapping the contents of of the nested routes with Indus HTML structure so to demonstrate a point let's create a navigation So within the body tag I'll
[08:21] just create a nav section with enough or create an unordered list and let's give this list two items or create a blog item as well as dashboard it save this and after saving this we can see these two items showing up at the top of the page so as per the layout the first thing we Define is the navigation followed by the contents of the pages that is why the navigation is showing up first then followed by the contents of this page file the layout is also
[08:52] inherited by any nested routes so we can demonstrate that by going to localhost 3000 and we can go to our blog route and within blog we can still see this navigation bar let's try something like dashboard within dashboard we can see those items and we can draw in Deeper by guiding the dashboard setting things and within the settings page we can still see the contents of the layout file it is important to note that we can have more than one layoutfall in our project because this layout fall is sitting in
[09:24] the root of our project this layout is applied to all files within the project itself if we wanted a specific layout for the dashboard we can do that as well so within the dashboard folder we can simply create a layout file called layout.jsx we can then create our layout by typing export default function root layout which takes in the children prop and we can now return any layout which wraps the children property so I'll list this out by adding an H3 tag with a text
[09:57] dashboard layout and let's save that if we go to our dashboard route we can see the dashboard layout text being inherited from the layout file this layout file is also inherited by any nested routes within our dashboard folder so if we go to dashboard slash settings we will also see the layout changes reflected here so it's important to note that the layout files only apply the changes to page files that are sitting at the same level as the layout file as well as any nested routes the
[10:30] layout will not be applied to parent folders or Pages let's now also have a look at metadata metadata is critical for SEO and it is really easy to implement in next 13. if we guide you our root layout file we can see this export object for metadata and also in our project in the browser if you have a look at the title we can see the title create next app this text is coming from this title in the metadata you can go ahead and change this to something like
[11:01] next route tutorial if I save this we can see the change reflected on this page this metadata change will also affect any nested routes in the project for example let's go to our dashboard route in dashboard we can see that title next raw tutorial but let's say we wanted a different title for the dashboard route we can do that quite easily by copying this metadata object we can go to dashboard within dashboard let's go to the layout page and at the
[11:31] top of this page We'll add the metadata object this gives us a different title like dashboard after saving this change we can see our title was changed as well I also want to mention that if you wanted a specific title for a route that doesn't use a custom layout file then you can actually add this metadata object in the page itself so I'll just copy this and let's go to our blog folder so in the blog folder we don't have a layout file we only have the page itself so at the top of this file I'll
[12:04] paste in this metadata object and let's change the title to something like my blog and let's save this let's go to the blog route and within block route we can see that title showing up as well so for the metadata object you've got the option of adding it to the layout file or to the page file itself next let's talk about navigation let's go back to our home page for this I'm actually going to close all of these files and let's open up our layout file in our layout file we've got this navigation section over here and I want to make
[12:36] these links clickable so to add links to next.js we can import the following at the top of our file I will import link from next slash link I will then wrap this text in a link component like this and the link component takes a property called hrf and within href we can specify the route that we want to navigate to So for this I'll simply make it slash blog and I'll do the same thing for the dashboard link like so and in
[13:06] the browser we can see that these two items are now clickable so let's test it out I'll click on blog takes us to the blog page let's click on dashboard which takes us to the dashboard page we can also programmatically navigate two pages using the use router hook we can test this out by going to dashboard and within dashboard I'll actually remove this div and replace it with a button with some text like go home so we can see the button here on the button I want to add an on click event and what I want
[13:38] to do is when we click on go home it needs to trigger the use router hook that comes standard with next.js so we need to import this Hook from next so I'll import something from next slash navigation and what we want to import is the use router hook then within our page component we want to create an instance of this hook so I'll do that by saying const router equals use router and what we can do then is when the button is
[14:10] clicked this will trigger an anonymous function and what we want this function to do is to call router dot push we can then specify the route that we want to go to for this example we'll just go back to the home page let's save this and after saving this we get this error message that says that use router only works in client components this is something that we'll have a look at in depth a bit later on in another video but basically with next 13 all components of server render components
[14:41] by default which means that when we access a route it will first be rendered on the server and then return back to the user this means that certain functionality like hooks are not available on the server and in that case we need to specify that this component is a client component Instead This is really easy to do all we have to do is go to the top of the page and then in quotes write use client and after saving this the error will be resolved and we should be able to test the button now if
[15:13] I click on go home we are instantly taken back to the home page of the project just one more comment on navigation these pages are actually prefetched so as you hover over these links the content of these pages are actually cached which speeds up navigation to these Pages we can see this in action by going to our developer tools and by going to the network tab I'm going to refresh the application and after the page is loaded we can see all of this content here but notice what
[15:44] happens when I hover over any of these links like dashboard we can see that the dashboard file has actually been loaded into memory and when we click on dashboard the pages returned almost instantly the same thing happens if we hover over the blog page and we can see the blog page was pulled in as well let's now also talk about Dynamic segments also known as Dynamic routes so in this example let's think about our blog page where the content is dynamically rendered on the screen so typically when we click on any of our
[16:15] blog Pages typically the navigation would be something like blog slash and Then followed by the article ID or maybe a slug Etc so because this name is dynamic we need to create a dynamic route within the blog folder so let's do that now we can create a dynamic route within the blog folder by creating a new folder and then type a square bracket followed by something like ID or slug this is really
[16:46] up to you and then closing that off with a closing square bracket within this folder we can now create a page file and just like with the other page files we need to export a default function we can give this function any name I will just call it something like blog post and this function needs to return some HTML or return an H1 tag for now with the text I am a blog post let's save this and if we refresh this page now we'll
[17:17] get the stick saying I am a blog post our Dynamic routes work is within the parameter list of this function we will receive a property called params and we can see the value of params by writing it to the console let's actually do that now in the developer tools I'll go to the console and let's refresh this page and because we didn't specify use client this page is considered to be a server render component and therefore the logs are actually written on the server and
[17:48] not on the client but in this terminal we can see our property coming through with a property called Slug and this name is pulled from this Dynamic value in the folder over here and the value of this property is article and just to show you what a client component would look like is let's add use client at the top of this file and hit save this and office saving this change we can now see this plug pulling through on the browser let's replace this text with the slug value so I'm just going to remove this
[18:19] we'll add curly braces followed by params.slug and we can now see that text pulling through let's change this to something else like paste and we can see that value pulling through let's also talk about catch all Dynamic segments if I had to add another nested route to this something like Test 2 we will actually get a 404 error because it's expecting us to create another nested route within the slug folder and it is completely valid to do that but let's say we wanted this page to deal with all
[18:52] parameters coming in so what we can do is rename this folder and install this value with three dots so dot dot dot slug this one I'll convert this route into a catch all route so irrespective of how many segments we pass after this route they will be pulled in by this page so let's add a test three as well and let's see what happens and if we have a look at our slug value in the console we can see that the slug is now an array with all the segment values
[19:24] being paused into it there's also a concept called optional catch all Dynamic segments it's very similar to The Catch All segment that we just had a look at it basically makes all of these segments optional so let's say we didn't pause any other values in we just specify the block page but maybe we want the block bytes to be triggered whether it's the blog page or whether there's additional segments added to it so what we can do in that case is we can rename this slug file we can start it off with
[19:56] a double square brackets and we can end it with double square brackets and at the moment if we visit this page it will actually take us to the page file created in the blog folder but what we can do is delete this page file and then if we refresh this will actually she trigger the page file within the slug folder so this is really a catch all now whether we specify any segments after this or not this Blog Page will be triggered if we don't specify any segments after this the params attribute
[20:28] will simply be an empty object let's also talk about a concept called route groups a route group is a way to uniquely organize your routes without affecting the final URL so as an example let's say that the dashboard route is considered to be a part of the administrative features available to the user we can create a route Group by creating a new folder the folder name then is to use parentheses within the parentheses we can give the folder a
[20:58] name like Administration in this case what we can do then is we can move our dashboard route into route group so after moving the dashboard route into Administration it will look something like this but it's important to note that the value in the parentheses does not affect the URL so back in the browser you can still guide the dashboard and our route is still working there's no need to type in something like Administration dashboard we can
[21:29] also use route groups we can also use route groups to assign dios to specific pages so let's look at our dashboard as an example in dashboard we have a layout file that is applied to the main dashboard route as well as the nested routes for account and settings but let's say we wanted a layout that affects account as well as settings without having to create another nested route for that so what we can do is in the dashboard folder let's create our route group with parentheses and let's
[22:01] call this something like I don't know something like account route as an example and then let's move account and settings into this folder after doing this we can still access the net tested routes within dashboard like this kind of settings as an example and the addition of this account without folder is not affecting the URL so what we can do now is within the account route folder we can create a new file called layout.jsx I'll actually just go and copy the contents from another layout
[22:31] file and I'll paste that into this file and let's change this text over here to account route or something like that and now we've got a layout that affects only the account and settings folders without affecting the URL let's also have a look at the loading file so within our app project let's create a new file called loading.jsx this naming Convention of loading is a reserved name in Next 13. we can create our loading file by
[23:03] exporting a default function called loading and then we can return any HTML code that we want and what I'll do is I'll actually return an H1 tag with the text loading so how this works is while the content in the page file is being rendered this loading component will be displayed so this file is a very good place to put in something like a loading spinner or just some text like we're doing here it's very difficult to test this out at the moment because it's loading so quickly but what I'll do is
[23:33] I'll actually force a loading state so in order to test out the loading State I'll add a one second delay to our root page file so what I'll do is I'll create a new function an async function called get data so for now I'll just create this throwaway function called get data and let's say that this function we call some API to fetch data and it could take a few seconds to resolve so all I'm doing is I'm creating a new promise which will complete after one second so in our home component let's call this
[24:05] function by awaiting get data we also need to convert this function to an async function and that should work so we we refresh this page we should see the loading text did you see that I'll try again great we can also add our own 404 pages so let's try that out if we try and access a route that does not exist something like localhost 3000 slash test we get this 404 message we can create
[24:35] our own custom 404 page by going to the app directory we can create a new file called not Dash found.jsx in this file will export a react component or give the page a name like not found and let's save this let's go ahead and refresh this page and now we are getting our own custom 404 not found page I think we've covered quite a lot in this video and there are more reserved files that we can have a look
[25:06] at as well as an example the error file but we'll have a look at that in a future video we also didn't have a look at this API folder yet and this is something we will cover in depth in a future video but in a nutshell we are able to create our own custom API routes using the API route Handler solution I hope you found this video useful if you like my content please consider subscribing to my channel and please like this video I'll see you in the next one bye bye