Statically Generate Pages using SSG and ISR with Next.js getStaticProps and getStaticPaths

Lazar Nikolov
InstructorLazar Nikolov

Share this video with your friends

Send Tweet
Published 2 months ago
Updated 2 months ago

‘Static generation’ (SSG) generates data at build time or when we run npm run build. It will generat all of the HTML files for us, which we then served statically. This makes our website fast for the users that visit it.

In Next.js, SSG is achieved through a getStaticProps function. This function can be exported from any page in Next.js and will fetch and build data for that page at build time. Next.js Strips this method from the bundle so it’s safe to use database connections and API secrets inside of.

You will often need to generate dynamic pages in combination with getStaticProps. To do this you will need to also export a function getStaticPaths that tell Next.js what pages to generate.

After you learn the getStaticProps api and what SSG looks like when you build, we’ll add set revalidate to an interval inside of getStaticProps which will let us tap into Next.js’ Incremental Static Regeneration feature. This will have the server rebuild the data at a set interval so our site can update for new users.

Lazar Nikolov: [0:01] All right. Since you understand now how data-fetching methods work in Next.js, we can start to implement them.

[0:07] In this lesson, we're going to cover the static generation or SSG, and the incremental static regeneration or ISR.

[0:15] Let's open Exercise 12. Let's open the pages directory, and the index.tsx file. This is our home page. One thing that you can notice is that this component now accepts props, which in this case is a string array called genres.

[0:32] These genres are then mapped out in a list. This is how we obtain the data from any data-fetching method in Next.js through the props.

[0:42] Let's implement the static generation method in this page.

[0:45] Just a quick refresher. The static generation generated the data at build time or when we run npm run build. It generated all of the HTML files for us, which we then served statically.

[0:57] Let's begin.

[0:58] To use the static generation method in this page, first, we need to import the getStaticProps type from next.js. So, we'll do import type, getStaticProps from next. Now, let's go to the bottom of the file. Just above the export default, we can export a new method called getStaticProps.

[1:17] Let's also set the type of this method to getStaticProps. Since it's a generic type, we can pass our own props to it. Inside of the method itself, we can do return props and then our prop type define genres. Genres, and we can define rock, country, and pop. That's it.

[1:43] Let's run npm run dev to see it in action. There we go. We have the genres title and we have the list of genres that we passed. If we add another one let's say, indie and refresh the page, we can see the new genre in the page.

[2:05] This is the simplest form of the static generation data-fetching method. One thing to note that the getStaticProps method must be named as getStaticProps in order to work.

[2:16] Also, Next.js strips away this method from the bundle. Meaning, when the user visits the home page, they will not receive this method, and they won't be able to look at the code. That feature makes this method safe for us to use database connections, or any API secrets that we don't want to be exposed.

[2:35] The static generation for dynamic routes or dynamic pages, requires some additional configuration to work.

[2:42] Let's create our genre page. Right click on the pages directory, New File. Let's call it genre.tsx, but with brackets around this name to make it dynamic. Let's create a genre component. We'll return a Hello text and export default genre.

[3:03] Let's implement the basic getStaticProps method here. First, let's create a type props for our props and we can say, "Genre is a string." We will display the genre in this case. Now, we can add the props type to our props on the component. Then we can replace the Hello text with the genre from the props.

[3:30] Awesome. Now, we can do import type getStaticProps to import the getStaticProps type from the next package, and export the getStaticProps method.

[3:42] We need to return an object that contains the props. In this case the genre, let's hard code it to rock. Since the static generation builds all of the pages at build time and this is a dynamic page, we need to tell Next.js which pages it should generate for us.

[4:00] In order to do that, we need to export another method called getStaticPaths, which return an object with the paths that we want Next.js to generate for us. Let's also import the getStaticPaths type from next, and export another method called getStaticPaths, which uses that type. getStaticPaths.

[4:24] As I mentioned, we need to return an object that included the paths and let's say, for example, we will only support rock, country and pop for now. We need to map these genres and return an object for each genre that has the params property. Inside of the params property, we need to add the genre.

[4:48] Aside from the paths property, we also need to provide a fallback property and set it to false. The paths property tells Next.js which pages it should generate. In this case, we want to generate rock, country, and pop.html files.

[5:04] The fallback property is a key that we must include in our getStaticPaths results. If it's set to false, like in this case, then any paths that are not returned by the getStaticPaths method will result in a 404 page.

[5:19] In this case, we have the indie genre, but since it's not included into the paths, it will result in a 404 page. If we set the fallback to true, Next.js will render a fallback page while it statically generates the HTML and JSON for this page. This includes running the getStaticProps again.

[5:39] When it's done, the page will receive the brand new data in its props, and it will render its contents. At the end of the process, Next.js will also add the new path to the list of pre-rendered pages. When we visit the indie page next time, it will not regenerate it.

[5:56] We can also set the fallback to blocking. This is very similar to the true value. In this case, Next.js will not render a fallback page, and it's going to make the browser wait for it to generate that page.

[6:10] Let's bring it back to false. Before we continue, let's go back to the index page and make the genre links.

[6:20] We're going to import the link component from next/link and wrap the genre with it. We need to provide an href. It will be "/genre." For rock it will be "/rock." For country it will be "/country," etc. Let's save this.

[6:39] As we can see, the cursor changes. If we click on "Rock," we can see that we navigated to /rock. We can see the genre name displayed. If we go to country, we can still see rock because we hard coded it. Let's go back to the genre page and let's fix that.

[7:00] Since this is a dynamic page and the getStaticProps method doesn't get sent to the user, we cannot use the use router hook that we used previously to figure out what is the current genre. We can check the genre from a different place.

[7:14] The getStaticProps method accepts a context in these arguments. The context is an object that holds data like default locale, locale, and locales, which are internationalization properties.

[7:25] Locale is a string array that holds all of the supported locales. The locale is the currently active locale. The default locale is the default locale. Then we have a property called params. These are the route parameters for pages that use dynamic routes just like this one.

[7:44] Then we have the preview Boolean, which is true if the page is in the preview mode. That's an advanced feature, and we won't be covering it in this course, and also the preview data which holds the data if the page is in preview mode.

[7:58] Let's obtain the genre from the context.params property. We can write const genre = contexts.params. This could be undefined. We need to optionally try to obtain the genre from the parameters. Because the parameters return a string or an array string, we need to cast it as a string because it's a single segment in our case.

[8:21] If we're unable to obtain the genre from the context, we can return a new object and set the notFound property to true. This is a known property to Next.js. If it receives a notFound Boolean set to true, it will render a 404 page. If the genre can be obtained, instead of hard-coding it, we can return the genre.

[8:45] Let's refresh and see what changes. There we go. We are in the country page, and we can see country. If you go back and open the pop page, we can see pop. If you go back and open the indie page, it will result in a 404 page because we did not include it into the getStaticPaths method.

[9:07] If we set the fallback to true and hit refresh, we can see the indie genre displayed there. This is how we can implement static generation in dynamic pages.

[9:19] To make sure that we actually use static generation, we can check from the Next.js build output. Let's run npm run build and see the output.

[9:31] There we go. Here is our home page and here is our genres page. As we can see, they are marked with a filled-in circle before them. If we look down at the legend, we can see that the filled-in circle represents an SSG page automatically generated as static HTML plus JSON or uses getStaticProps.

[9:55] In order to demonstrate that we are fetching the data at build time, we can add a simple console log statement in the getStaticProps. We'll say, "Fetching data in getStaticProps. If we run npm run build again, we can see the output fetching data in getStaticProps three times.

[10:20] We have four pages. Why is that? We had three pages into the getStaticPaths. Next.js will only generate the HTML for those pages, but not the indie, even though we saw it because we had the fallback true.

[10:37] Let's run this. We'll do npm start. We can see the fetching data in getStaticProps gets outputted again because we are in the indie page.

[10:49] As we mentioned, we did not include it into the getStaticPaths method. Because we set the fallback to true, Next.js regenerates it. Meaning, it will execute the getStaticProps method again, and that's why we can see the console output here, and it will add it to the pre-built website.

[11:09] It doesn't matter how many times we refresh, we can only see the fetching data in getStaticProps logged out just once. If we go back to the rock genre, country, or pop, we will not see the fetching data in getStaticProps.

[11:24] All right. That's how you implement static generation or SSG.

[11:28] Now, let's look at the Incremental Static Regeneration or ISR. To use ISR in this page, all we need to do is return a revalidate property after the props, which will be the number of seconds in which the server will revalidate the page only once. For testing purposes, let's set it to five.

[11:49] In order to see that, we need to rebuild the page. npm run build. We can also make sure that we're using ISR. There we go. If you look at the genre page, we can still see the filled-in circle, but now we have ISR of five seconds. Good. That means we are using ISR.

[12:07] Let's run npm-start to run the server, and reload this page. As you can see, we have the fetching data in getStaticProps logged out, even though we had the pop genre supported in the getStaticPaths.

[12:24] If we run refresh again, we can see the fetching data in getStaticProps gets logged out again. This means Next.js will execute getStaticProps again. If there's new data, it will be included. If we start refreshing, we can see that the fetching data in getStaticProps gets logged out on roughly every five seconds, but not on every refresh.

[12:48] If we stop refreshing and wait for five seconds, the fetching data in getStaticProps will not be printed out. As we mentioned, ISR does not function like a cron. It will not regenerate on every five seconds.

[13:10] If we refresh now since five seconds has passed, we should be able to see another fetching data in getStaticProps log out. Let's try that. There we go. This is how you can implement ISR. Let's recap.

[13:25] We learned that we can obtain the data fetching methods data through the props, just like we can see here. To implement the static generation method, we needed to import the getStaticProps type from next, and export our getStaticProps method.

[13:45] We learn that this method was safe for us to use any database connections or API secrets, and we can prepare our data anyway we like. We need to return the data, then we can obtain it from the props. This was for static pages.

[14:03] Then we learn that for dynamic pages, we also need to export getStaticPaths method that tells Next.js which pages should be generated at build time. In our case, we generated rock, country, and pop.

[14:17] We learned about the fallback property and the different behavior that it can provide. We also learned how to enable Incremental Static Regeneration or ISR by providing the revalidate property.