Next.js App Router: Routing, Data Fetching, Caching

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
This video will be an overview of some of the new concepts and foundations in the Next.js app router as it's now almost towards full stability. Let's take a look. Okay, let's start with routing and I'll introduce our first convention, which are layouts. So one of the great new features of the Next.js app router is built-in support for improved ergonomics around layouts as well as supporting nested layouts. So in the app folder or app directory, here we have a new file layout.tsx because I'm using TypeScript and this defines the route layout for my application. So, as you'll see, it exports a default function, the route layout, which takes in some children, it renders those children in an HTML tag, and this is what we're going to initially see when we visit our application at localhost:3000 So let's go to localhost:3000. Our application loads, and we see Hello, World! Now, inside of this layout, you'll notice that I haven't defined the text. "Hello, World!" anywhere, now the foundation of the Next.js app router is composing different React components and this is how layouts work at their core. So this component is actually composing a page, which is another convention we can introduce. So we look at the page file denoted by a special page.tsx file name. We see that there's a default exported React component that returns some jsx in this case, an H1 saying, Hello, world! Now, this is what we're actually seeing over here on the browser that is making this an addressable piece of UI. So if I open up our dev tools and actually inspect the output here, we see the HTML tag the body tag, and then the H1 from our page. So the layout and the page were composed together. By default, all pages and layouts inside of the app router are React server components by default. Now this is a new way of programming with React. By default, this means that your code only runs on the server. So for every new additional component you had in your application, it's not sending any additional JavaScript to the cient side, it's securely running only on the server. Then, when you want to introduce more code on the client side you'll have client components for interactivity. But first, let's finish off talking about routing. So we have our index route here defined by this page in the app directory but if you want to create a new route we have to create a new page file. So what I'll do is I'll make a new folder and we'll call this about; and then inside of that folder, I can define a new file page.tsx, and then we can just put in a default exported React component here that returns some H1 that says, "Hello, About!" So we go back to our browser and navigate to /about, we see that we have our new text displayed in the browser. So, the file system based router that you love of Next.js, still remains and is improved and enhanced with the app directory. Just like the pages router, this supports more than just static routes We could also have dynamic route segments. So for example, if I go to our app directory, I make a new folder, let's just call this blog, and then inside of the blog folder I make another new folder we'll say [id] and we'll use these brackets here these square brackets to denote that this is a dynamic route segment and then inside of that folder, we'll define a new page. So just to recap here, the page is what marks the UI as an addressable route that you can navigate to inside of your browser. So let's say that we have another React component here, we'll just call this blog, and if I go back to my browser, and I go to /blog /123, we're going to see this new page rendered. Now of course, most of the time you also want to read that dynamic route segment and you can do that very easily by accessing the params key inside of the props of your component. So in this instance, I've destructured that object, I've pulled out the params key and then I can use params.id inside of my jsx to render out the ID of this route segment. So if I change this to 345 for example, we're able to see that new value in the browser. As a quick note, you can also access the URL searchParams as well inside of the props for pages. Now that you have your routes to find, you might want to also navigate between them and you can use the built-in Next.js link component that you know and love from the Pages directory. So, I went back to our index route I've updated the default exported component here to render out a link component which just renders an a tag under the hood and that's going to navigate to the /about route. So, if I click on this link, you see that we very quickly transition between our pages using the link component. This also supports routes with dynamic route segment as well too, like blog/123 for example. Okay, so you have your routes now let's talk about data fetching. So we want to get some dynamic data inside of our component and display it on the screen. In the pages directory there were Next.js specific APIs like getStaticProps and GetServerSideProps that enabled you to do this but in the Next.js app router we've taken the opportunity to drastically simplify how data fetching works by building on the latest React innovations. So to do that, let's take a look at how we can fetch some data inside of our index route. We'll start by marking our component as an asynchronous component. Remember, these are React server components. So they securely run on the server by default. Now our component is able to support awaiting some promise inside of the body here. So let's say I want to do const response equals await in this instance, I'm getting a suggestion to fetch information back about the Next.js repository. Then once we have that response, we can get the JSON from it and then inside of the jsx we could actually consume that data. In this instance, I will just update this instead of JSON we'll call this data and I'm not exactly sure what it's going to give me, but we're going to give it a shot. Ok, so there is an ID here. If I wanted to, I could click into this and see the format we're working with ID, name, full name, all these different things. Let's make this a little bit smoother by using TypeScript. So I'm going to go to the top, and I'm going to define a type and let's call this a Repository. And it has an ID, looks like it has a name, it has a full name, all this looks good. Inside of the app router, it's a lot more simple to get great support for TypeScript out of the box. So for example, I make a fetch to get some data. I get that data back and now I want to mark this data as a type of repository. Now when I'm rendering out that code inside of my jsx and I hit data [dot], I can see all the different options that I have and if for some reason, I had the wrong type here, my editor would give me that helpful feedback. So let me change the full name and I'll go back here and I see vercel/next.js. Now since this is just a promise, You can structure this however you want. This code could come from an external npm package. You could pull this out into some function here, get data where this kind of functions like hoisting up your code similar to the patterns and getStaticProps or getServerSideProps You could do that if you wanted, you can move this to a separate folder, the pattern that I like right now is just trying to put this inside my component until it feels a little bit more natural to break things out. Now, something that's really powerful with this pattern is that we can fetch data in more than just our pages. So, previously in the pages directory your data fetching could only happen inside of that pages directory itself, building on the foundations of server components, in the Next.js app router, we can fetch data in any server component. So what I've done here is I've actually pulled out that data fetching code from our index page here, and I've instead put it into the root layout. So instead inside of this route layout I marked it as async I moved this data fetching code here and then I rendered out the full name inside of the body. Now, this means that this data is essentially up one layer in our tree and can be shared when I navigate to different routes. If I go to /about, I see that, I still have the full name of my repo that I fetch dynamically as well as having the composed content from the about route. Ok, so you might be wondering, this looks great, I can await some promise, but how do I use the other powerful features of Next.js like support for static data, dynamic data, or data that gets revalidated and what you're seeing here by default, is that all of your data fetches are static. So for example, if we were to do a production build here and run this wherever we want to deploy our initial application, this data would actually be cashed static for the entirety of our application and it would also work if we wanted to inject out a static export of our application. Now, if you wanted to emulate the behavior of having some dynamic data on every request, we can also do that by extending the web fetch API So let me pass some new parameters here. We're going to pass in cache, and we're going to say no-store. Now this no-store option means that on every request we want to bypass caching and we want to fetch new data. To better emulate this, I went ahead and changed out the API. I was using to a remote API, that dispatches back the current time so I have the cache no-store saying that I want to run this on every request, I change the type which returns back this datetime and then I'm consuming datetime down here, and now you notice every time I refresh, I get that new value for the datetime. Now this also supports data that we want to revalidate, otherwise known as incremental static regeneration. So I replaced the cache argument here to our fetch API and I instead used next. Now next is going to be Next.js specific APIs that we want to include on top of fetch, and we have a key of revalidate that's defining a time of five seconds. So at most we're going to see this value change every five seconds. So if I refresh over here, I see a new value come and I refresh, refresh, refresh. This is only going to change after five seconds has elapsed here and it goes to that API and retrieves the new value. Now, this is where I'm going to blow your mind. Previously, in the pages directory, your data fetching strategy, whether it was static, dynamic, or ISR was the only strategy that you could pick for your entire route. Well, everything I've just shown here, can actually be used together inside of the same route. So, what I've done, is I've actually combined the last two examples into our index route, I have this function getTime that returns a promise that returns a time object I have another function called getRepo, which returns a promise that has our repository information, and then inside of our page, I'm using promise.all to fetch these in parallel and then I render out the name of the repository as well as the datetime. Now watch what happens in the browser when I refresh. I get a new time and I keep refreshing and I'm getting the same static data. But then five seconds elapses, and I see the new time come in. So the top, this data fetch for the repository name remained static the entire time and the data fetch below used ISR semantics. So you can combine all of these inside of routes, for the most flexibility. It's all built on top of the powerful Next.js cache which you can learn more about in our documentation. Okay, switching gears a little bit. Let's talk about preparing your site for sharing on the web. Now in the pages directory, you could do this by using the next/head API, which allowed you to update the content inside of your head element, like meta tags or link tags. Well inside of the app router, we've completely revamped this to have better, built-in SEO support with a powerful new metadata API. Let's look at an example. So if you see here, we have this metadata object that has a title and a description, and then if we look at the output inside, of our HTML here, we see that we have a title tag that says 'Create Next App' we have a meta description tag that shows what we've defined. So we built this API that makes it really easy to find your metadata and it maps to the corresponding linked tags for you, so you don't have to manually update the head element. This metadata object, or API, supports basically every single way that you wanted to find, metadata in your application, on the right here, I have the docs pulled up if you want to go give those a read, You can see all the different ways you can configure metadata in your application, all defined inside of the keys of that object. Now sometimes you want your metadata to be based on dynamic data. Like, in this example, we have a blog post at /123 for the route segment. The static metadata approach will work here. So we also have an API called generateMetadata that takes in the same params as the default exported page and allows you to return an object that uses that exact same metadata API. So, for example, if I put the title to my blog post and I hit save on the right, you see that the browser updates and I see the new head of my blog post get populated with the title tag. Now, again, this uses the same data fetching primitives where you can call any promise, whether that's from your database, whether that's using the fetch API, and these are automatically deduplicated. To demonstrate this, I just went ahead and refactored the last example to make the route here, /repo/name, where name is the dynamic route segment and this function getRepo now is actually reused in both generateMetadata as well as our asynchronous component here. It's actually rendering out the name of the repo. So for example, if I was to change this from /repo/nextjs to /repo/turporepo, we see that we get our new data. Now, while I could keep going and talk about some of the things in Next.js you already might know and love, like image button, script optimizations or even some of the new stuff we're working on it might already be out by the time you watch this video. We'll call it a wrap for now, hopefully this was helpful to understand some of the new conventions and foundations of the Next.js app router Give our channel a subscribe if you you want to see more content on Next.js and React, and until the next one, stay tuned.
Info
Channel: Vercel
Views: 132,025
Rating: undefined out of 5
Keywords: next js, next js tutorial, next js app, next js app directory, nextjs 13 app, next js 13 app directory
Id: gSSsZReIFRk
Channel Id: undefined
Length: 14min 31sec (871 seconds)
Published: Tue Apr 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.