For our personal portfolio site, we definitely want to have a blog or list of articles. If we want to display articles, we might have a routing like
In this lesson, we learn how Next.js uses a folder-based routing system and in particular why
getStaticPaths is useful for creating a dynamic Next.js page component that renders the article based on what is in the URL
Prefer to read along as well? Here's the accompanying article.
Instructor: [0:00] In our About component, we have now seen the getStaticProps, which we're using here for passing on data to our Page function. The next thing we want to have a look at is the getStaticPaths.
[0:13] If we jump over to the documentation, it clearly states here that this is intended for dynamic routes, so whenever you have dynamic routes, which we might want to have, because in our blog platform or our portfolio site, we definitely also want to have a list of articles which we publish.
[0:29] For instance, this could be yuri.dev, which is the domain, and then I might have a /articles, which is the list of articles, then / and some detail article. This could be Next.js with Nx, which is the ID of one specific article.
[0:44] This last piece here is definitely dynamic. We would have some placeholder, which would then be filled in with the ID of the specific article the user is viewing. This is exactly what the getStaticPaths is about. It states here that you need to define a list of paths that need to be rendered to HTML at build-time. Again, this is important, because we want to pre-render that at build time, and not dynamically.
[1:10] From the structure point of view, you can see here, we return an object. We have that paths array in there which, again, then takes a set of parameters. These would be the ones that we will then pass on to the getStaticProps, which we have seen in our About component.
[1:27] Then, there's also that fallback. The fallback, in general, is a property where you could say, if you set it to false, that means that if Next.js doesn't find that component pre-rendered, it would stop and give you a 404.
[1:42] If you provide true, it would call back to the server and try to dynamically render that ad hoc from the server side. In our case, we want to pre-render all of our articles, so we would go with false here in our case.
[1:56] Let's go back to our application and actually implement this. In terms of the routing, you can see, whenever you have such sub-pieces in your URLs, such sub-paths, these are 1:1 reflected on your file system. Next.js has a conventional-based routing system, which would mean that, here we would have the Pages folder, and under that, we would have our Articles folder, and there, that Slug page component.
[2:23] Let's again use Nx generators to help us generate that component. I use yarn nx generate -- or I can use g for generate -- @nrwl/next, which is the plugin that has the generator, name of the generator's page, and I give it the name, which is in this case, Slug. I use those square brackets. That is the convention to tell Next.js that this is a dynamic one.
[2:46] I don't want to have styles here, so I pass style:none. We also want to make sure to say, directory = Articles, because we want to have that in Articles directory. I'm using the dry run here first to see what would actually happen, to make sure it is the correct one. We can see, we would generate that Articles folder, as we mentioned here.
[3:08] It's also interesting that the page generator, as you can see, already knows it should generate a component under that Pages folder inside our application. That's already handled by us. Then, we have that Slug component.
[3:21] Let me remove the dry run and actually generate this. We see that Articles folder and our Slug page component. We would definitely want to adjust a couple of things here. We want to not call this as Slug properties, but rather articleProps, so it is our article. Similarly, here, a component which we would call Article. That should be it for now.
[3:42] As the first thing, let's implement that getStaticPaths. Let's create the function. We also want to export this one, getStaticPaths. We also want to type it, since we have TypeScript set up. I'm using here the articleProps for now. Definitely, feel free to choose a different interface, and not reuse the same as the actual Page component takes in. That's up to you.
[4:06] Then, this is an async function, doesn't take any params. We can create the scaffold like this. We have seen, we need to return an object, overall, which has that parseArray, and also the fallback property, which, as I mentioned, we set to false for now.
[4:21] This sets us up for the getStaticPaths. We can fill in here the details. For this simple example, let me statically add in here some objects. Each object has a params that it should return. These are the ones that would then be passed on to our getStaticProps, which we'll create in a minute.
[4:41] Here, let me create a slug, and let's call this page 1. This would be the identifier of the page. You can imagine this slug here would replace here this piece, and therefore, render a component per page. Let's repeat this and let's create another object, and return this in our array here. Cool.
[5:03] The next thing would be to go and create the getStaticProps. To be quicker, let me copy that over from our About page and paste it in here. Again, we want to import the typings, and this would be articleProps. I'm reusing again here the interface for now. We would get here that params object from our getStaticPaths.
[5:26] Let me just destructure that. That would be an object where the params property is of type ArticleProps, so they match up. Down here, I would just want to return something. I could definitely take those params and process them. To keep it simple for now, let's just here change this line and return here, slug. This would be params.slug.
[5:51] So far so good. You can see we have some TypeScript issues here. That's, obviously, because we didn't update here our interface. We have here slugString. We should also implement here, the parsedURLQuery. That's something that getStaticPath expects.
[6:12] The TypeScript errors are gone. We should be good. Obviously, we should also reflect the changes in our Articles component. Basically, what you can see now here, we get from the params, the actual slug, and we just forward that for now, we proxy it through in that props object. We learned before, that the props object is being passed to the actual component, then.
[6:33] Here, we could just say something like VisitingProps. This should be then Visiting, here, page 1, if we are on page 1, and page, let's say Two, if you're on page 2.
[6:47] Let's serve the application. If we switch over to our browser and go to localhost:4200, our app renders. The About page still renders. We should also be able to go to articles/page 1. You can see now, Visiting Page 1. If we go to page 2, it would be Visiting Page 2.