Next.js has two forms of pre-rendering: Static Generation and Server-side Rendering.
If the data required to render the page is available at build time ahead of a user’s request (e.g. a list of blogposts) it's possible to generate the whole page at a build time of the app to ensure the best performance & SEO.
In this quick lesson we're going to learn how to use getStaticProps
in Next.js with TypeScript support to statically generate a list of blogposts from an external API.
Tomasz Łakomy: [0:00] Now that our blog has both static and dynamic pages, it is time to finally add some content. There's plenty of strategies when it comes to serving content on Next.js app. Next.js has started as a server-side rendering framework, but right now, it has also a Static Generation feature, which is exactly what we want when building a blog.
[0:20] A content of a blog is not likely to change very often, which means that we get to fetch data at the build time in order to generate all the pages that are going to live in our blog, in order to ensure the best performance and SEO possible.
[0:37] In order to do that, we're going to use the getStaticProps method from Next.js. The idea is that any page, and only a page, can export a function which is called getStaticProps. This function is going to be called at a build time in order to pre-render the page, and those props that we are going to return from this function are going to be passed into the page component.
[1:00] When it comes to the content, I'm going to use a JSON placeholder API to get a list of sample blog posts. Of course, you can use a headless CMS, or you can have Markdown files in your project. It is completely up to you.
[1:13] I would like to make things simple for now, so I'm going to use an external sample API. First, I would like to render a list of all of those blog posts on the index page. To do that, in the index file, I'm going to export const getStaticProps. It is a function which is going to first up call an API. We are going to fetch the JSON placeholder API.
[1:36] Next up, I'm going to get the posts, which is going to be await res.json(). Lastly, we have to return something. I'm going to return a props, and inside of those props, I'm going to return all those posts that we are going to get from this API.
[1:51] As a reminder, this function is going to be only called at a build time. You can even do direct databases call here, because this code is not going to be shipped to the user. Since this is going to be passed into our home component, I can just start with the posts over here.
[2:09] As soon as we do that, TypeScript is going to complain, because it has no idea what those posts are. Let's fix that.
[2:15] I'm going to create a type Post. We can see in our API that every post has an userId, id, title, and a body. userId is going to be a number, id is also a number, title is a string, and body is also a string.
[2:31] Now, we can tell TypeScript that those posts that we get over here are not of type any, because, in fact, those are an array of posts. Here, we can see that right now, TypeScript recognized that we are, in fact, passing the array of Post to our home component over here. Right now, we just need to specify a proper type for those posts.
[2:52] Luckily, Next comes with a type that can help us. From Next.js, I'm going to import InferGetStaticPropsType. We can use that to infer what exactly is being passed into this component. I am going to use it like this. We have to pass in the InferGetStaticPropsType, and we also have to provide the typeof getStaticProps.
[3:14] Right now, if I hover over here, we can see that those posts are currently recognized as an array of Post. Just to make sure that everything is fine, I'm going to console.log all those posts.
[3:25] Let me save that, go back to our blog, and we can see over here that we do get an array of 100 blog posts. Instead of this console.log, we are going to render a list of all of those blog posts. I'm going to paste in some emotion styled components, so we're going to have a List, a ListItem, and a PostTitle that will also add some JSX.
[3:45] Over here, we have a List. Inside of this List, we are mapping over every single post, displaying a ListItem with a key of post.id so that React is not going to complain, and inside of it, we are displaying a PostTitle with a post.title inside of it.
[4:01] Something to notice is that, if you wanted to also render a post.body, we do get type completion inside of our editor, thanks to TypeScript.
[4:10] Let me remove that and go over here to see the result. We can see a statically generated page, containing a list of all of our blog posts from the API.