Templates vs Layouts in NextJs 13

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to talk about templates and layouts in NEX 13 how they're different and when to use which we're going to also build a simple application where we can see this differences in action so let's go let's start from the documentation and see the file conventions that we have access to inside the app router in NEX 13 one of the files that we can use inside any route segment is this template. JS or. TS file which is a specialized re-rendered layout here I so this is referring to our layout now if you're not familiar with the file conventions or what a layout is uh I have other videos on the channel where I go in deeper details about this new file convention or specifically the layouts but from a high level a layout is just a component that wraps your page component so therefore you can have shared layouts between different route segments or you can have uh nested layouts easily by creating a layout doj file inside of any route segment now a template file is similar to a layout in that it wraps its uh chart layout and pages but unlike layouts that persist across routes and maintain their state templates are going to create a new instance for each children on navigation so what does this mean so let's go to our application to see this in action now I've created this simple NEX application where I have this top row navigation hether and also this nested layer out where I can just navigate between different pages the about page and the contact page I'm going to jump into the code and see where we're starting from in a second but what I'm trying to explain here is that that top row which is part of our layout is not going to render when I'm changing this routes that is going to be there and the only thing changing is this page this is also similar for this side navigation because this is also a nested layout so upon navigating between different pages inside of a layout these layout components are not going to reender they stay the same and the only thing which is rendered is this page component now if you use a template instead of the layout the only difference is that now on navigation between the these different pages for example if you're using a template here for this side navigation it is going to create a new instance of that template for each children if every time that you're navigating between different pages now you might wonder why would you want to use a template instead of a layout well some use cases may be if you're implementing any logic that requires or depends on use effect or use state things like logging page views which we're going to implement together or a pair page feedback form for example that has its own State you would want to use template because you want to recreate or resync your user effect or reinitialize the state every time that you actually navigate between different pages whereas if you're using a layout it's going to persist this state between navigations and it's not going to reender now the other use case is anytime that you want to change the layout's default behavior for example if you have suspense boundaries inside your layout the fallback that you have defined for your boundary is going to only render once and for the first time and any other time after that it's just going to show the fallback because if it has already shown the fallback once if you want to render your fallback for your suspense boundary every time on navigation you would want to use a template or that's an instance of you changing the default behavior of the framework so let's actually implement this logging page views and see this in action let me start by explaining what I've done so far or the starting point and then we're going to build on on top of it together so as I mentioned I started a brand new nextjs application and all I had done so far was to create this company route group if you're not familiar with route groups I'm going to include a link to a video that I've explained them in nexs 13 or inside the app router but from a high level route groups are for organizing your routes inside of a folder without affecting the URL so for example inside this company group I have an about page and a contact page but the fact of the matter that I have created this company inside of this parenthesis doesn't change the route so I can still access the about on for slab instead of going to for/ compan for slab so this route group doesn't affect the url url segments so inside of this company route group I have an about there is a page inside of it this page is responsible for rendering this about page and a contact page again similar concept cep with a component responsible for rendering the contact page and the beauty of this route group other than organizing my files into one place or one folder is that now I can share a layout between these segments that are inside of this route group so I have this layout where I'm actually rendering this part of it let me just close this off so you can see better uh my layout is receiving children this is going to be the nested child page component and it's rendering this side navigation and then it's putting this children which are going to be our different pages inside of this main which is this right hand side uh of this navigation so now any page that's inside of this route group is going to use this layout and these page components are going to be plugged inside of this route layout or be plugged inside of this children okay and now the last thing is our root layout so let me just quickly also show you this this is what comes out of the box the only thing that I've added is this Heather this Heather is going to now be shown for every page because this is the root layout which is shared between all of our page components I'm rendering those links up top so that I can navigate between my homepage my contact and my about page so let's just go back inside of our route group and see how can we go about implementing a logic that's depending on us effect for example to log page views so if inside of this route or comp any layout that I have let me just close this off if I want to just log something over here so I'm going to use use effect from react and all we're going to do here is to console log let's say logging page view so I want to count or log the number of page views to an um external system or in this case we're just Faking It by logging it internally now I'm using use effect which means I have to use a client component and I'm going to use a client component by adding this use client directive up top so let me just open up the console down here let me just also make this bigger so you can see so what we're doing here inside of the layout which is shared between all the routes or segments inside of this company Group which are about and contact and for each one we're just logging a page view okay so if I go to the about page you can see it says logging page view now the reason that it's logging it twice even though we told it to run once is that in uh strict mode react actually runs your effects twice to make sure that if you're doing anything wrong inside of your effects you know it before you actually go to the production if you want to disable that you can go to your next config and here we can say react strict mode and let's just turn this to false I'm going to save and I'm going to just stop the dev server and restart the dev server here okay let me just refresh this page okay let's open this in a new page close the previous one and also open up our console and now if I clear this go to the about page you can see this logging page view or the effect is only running once now watch what happens when I'm navigating between different pages so let me close this off if I now go to the contact page this effect is not running again it's not logging this page view again so as I'm navigating this is the only time that it was logged it was for the first time that this layout was rendered and that's how layout layouts are supposed to work they only render once and they do not reender on navigation when the page changes the only thing that's re-rendering is the actual page component here well while this is good for performance optimization because you're not actually rendering that layout that is not actually changing between these two pages the top navigation or the sidebar navigation are the same so there's no reason to reender them in some cases like this case that we want to actually log page views so we want to count how many times the user is actually seeing a specific page or actually navigating between different pages you may want to change this default Behavior here so let's actually see that in action by adding a template to this file so let me just go here and add a template. TSX to our file if you go back to the documentation for the template it has a very similar structure to our layout in that it is a function that receives a children and it just wraps the children with whatever component that you decide to in this case we don't want to wrap it with anything but what I want to do is that I want to bring in this use effect inside of this template and run it here so let's also import it from react here and now our template is a client component so I have to use the use client directive going to go back to the layout and actually eliminate the use effect and use client now our layout is a server component rendering this site navigation but we're also adding a template which is going to wrap our Pages inside of the layout to actually do this logging now before we actually test this I want to mention something about the hierarchy of this different files that you have inside of your route so if you go to the docs uh for routing uh just where they talk about the file convention you can see this components hierarchy let me just make this a bit bigger so these are the different files that you can have in each folder or in each route segment the layout the template error loading these are for actually rendering suspense boundaries error boundaries or the actual UI for your page now the way that this is going to turn in react components is that your page is going to be here wrapped with the error boundary wrapped with the suspense boundary wrapped with the template and the template is going to be inside the layout now you can use template on its own too so what we could have done is to just turn this layout into a template it is going to do the same thing it's going to just wrap every page component and we could have just added that use effect there I just wanted to show you that you can have a template and a layout and the templ the layout is just going to wrap your template okay that out of the way let's just go back to the documentation clear this out let me also refresh this page going to the homepage let's refresh I'm just getting rid of the cache that we have on the client side if I go to the about page now we can see the log page view if I go to the contact you see the number two is actually increasing the number of times or every time that I'm changing this it's running this effect again and again because this template is running again and again it's rendering so therefore it's rerunning this effect now let me also show you this difference between templates and layouts in a different way so imagine we want to add some animation to our navigation links on this side navigation so for this I'm going to use framer motion and I'm going to replace this uh links with motion from framer motion this allows you to actually run animations on elements framer Motion in general is a fantastic library for doing animations so I recommend checking it out I'll also do uh a video on it soon in the future but for the purpose of this video I just want to show these animations on this links on the site navigation so they have a little stagger and then they fade in when we actually open the page up but we're still inside of a layout which is going to make this animation only run once so let's see this in action so if I just go to the homepage let me clear the console if I go to the about page I'm going to get an error because now I have to turn this into a client component to be able to use frame a motions I also need to actually install framer motion so let me just go ahead and stop the dev server here and PMP add framer motion okay let me restart the dev server here if I go back to the home and refresh our application let me also clear the console here now watch what happens when I navigate to the about page you should see the navigation links on the sidebar actually animate in as you saw there but if I move to the contact page or switch between the two pages even though the pages are changing the routes changing the animation is not running again and this is because you're using layout and layouts only run once in the beginning and don't render this is for performance optimization and it's good because you're avoiding those whole react components to reender unnecessarily when nothing has changed now let's contrast this by running the same thing inside a template and watching this animation rerun so I'm going to copy everything inside of our layout and bring it inside of our template here let's just save this and I'm going to this time get rid of our template so instead of having both together I just replaced everything that I had inside of my layout but just put it inside of our template let's go back to the homepage and rerender now watch the animations running when I navigate to the about page but also every time that I'm switching between these two pages this is because now this component is running inside of a template file which reenders this component every time making this animations rerun every time that we switch Pages or upon navigation now I'm not suggesting to go ahead and add these animations to your sidebar navigation or change your layouts with the template it's just that to understand that layouts actually persist their state they don't rerun effects they only run once whereas templates actually render every time the route changes or user navigates to a different page now as far as the implementation goes behind the scenes for templates to have this Behavior if you go to the documentation for template file and scroll down you can actually see templates are regular components that just use a unique key to force react to reender the content of this component now this is a react specific feature it's not nextjs you can use a key prop a unique key prop on any component in react and that forces react to reender it here they're using the route parameters or the specific path that you're on as a unique key for our template to render and you can actually see our our template is also nested inside of our layout and that's rrap for this video folks I hope you learned the difference between templates and layouts and when to use which generally speaking you would want to stick to your layouts because they have this performance optimization by preventing similar components or components that haven't changed or your layout not to reender every time that the user navigates between different nested pages but if your specific use case requires actually your state to be rein instantiated or for an effect to resync or in this case an animation to rerun you can use uh templates you can replace them with the layout or use layouts and templates together to have that functionality that needs to rerun inside the template but also keep this stuff that doesn't need to rerun inside of your layout if you have any questions like always hit me up in the comments and I'll see you in the next one bye-bye
Info
Channel: Hamed Bahram
Views: 8,533
Rating: undefined out of 5
Keywords:
Id: JPX60qarij4
Channel Id: undefined
Length: 16min 54sec (1014 seconds)
Published: Sat Oct 21 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.