Understand Static Site Generation with Next.js

Take full advantage of static site generation.

We all love Next.js for the ability of server-side rendering. But we often fail to take advantage of the awesomeness of the static generation.

If designed properly, we can pre-generate almost every page of a website, and thus, our website acts as a static website. Fast and SEO-friendly.

But there is a limitation on how many pages you can pre-generate with Next.js. Today, we will take a shot at understanding the different use-cases of static site generation in Next.js.

How Static Generation Works Static generation means we will pre-generate our pages on the server-side and when the users request a page we will send them back the actual HTML file. This is the major difference between Next.js vs React which only supports client-side generation.

In order to statically generate our pages with Next.js, we need to use 2 functions.

getStaticPaths -> To know all the possible routes ahead of time getStaticProps -> To generate the required props for the page Let’s say you want to pre-generate all the blog posts of your personal website. The URLs looks something like /blog/{blogId}

In this scenario, the code will look something like this.

function Blog({ blogPost }) {
  return <div> { JSON.stringify(blogPost) } </div>
}

// get all the possible paths
export async function getStaticPaths() {

  // generate all paths
  const paths = getPaths()

  return { paths, fallback: 'blocking' }
}

export async function getStaticProps() {

  // get the blog details using blogId
  blogPost = await fetch(BLOG_DETAILS_URL)

  return {
    props: {
      blogPost
    },
  }
}

You should already be familiar with the syntax so I don’t want to elaborate. We will focus on understanding the different approaches to static generation.

The problem The main problem is there is a limit to how many pages we can pre-generate. You can check that on the vercel website. Generally, it’s 8000 pages.

Now depending on the situation, we have to take an informed decision on which approach we are going to take. And the generation works based on the fallback property.

There are 3 possible values.

  • false
  • true
  • blocking Let’s discuss the scenarios when you will use these different values.

You have a small website with less dynamic content If you are building a portfolio page there is a high chance that your pages are going to be pretty same over time and they will also fall inside the limit of 8000 pages.

In these scenarios, you have to specify the fallback = false

export async function getStaticPaths() {

  // generate all paths
  const paths = getPaths()

  return { paths, fallback: 'false' }
}

When you define fallback as false basically, you are telling Next.js to only serve static pages. So it works like a static website.

There are some implications though.

If any user wants to access any route that is not pre-generated then they will see a 404 page. Next.js will not try to build this page on runtime. If you change any content of your website(meaning add some new routes) you have to re-deploy the whole application again. Generally, it will assure that no unwanted routes are going to be served. And this approach will make your website almost behave like a static site. Huge website with lots of dynamic content If you have a website where the number of possible pages is huge and you want to present the users with a skeleton of the page (for good user experience). Then you should use fallback = true .

export async function getStaticPaths() {

  // generate all paths
  const paths = getPaths()

  return { paths, fallback: true }
}

Now if any user requests for a page that is not statically generated yet the server will not respond with a 404 page. Instead,

  • It will return immediately a version with no props (In this stage it’s our job to show the skeleton version)
  • It will try to get the appropriate props for the page (just like getServerSideProps) in the background.

Now the question is how do you understand when to show the skeleton and when to show the actual page?

For that, we take advantage of the router of Next.js. Inside your component, you will try to understand if the page has the required props available or not, and based on that you show the appropriate version of the page.

function BlogPost({ blog }) {
  const router = useRouter()

  // posts will not be available at the beginning. SO show the fallback version
  if (router.isFallback) {
    return <div>Loading...</div>
  }

  // render blog post...
}

This is a great way to generate static pages on the go.

The nice thing is once the user requests a page and it’s generated, the server will cache this page for subsequent requests. Which is very nice and efficient!

Dynamic content but no skeleton If you have a website where most of the pages are pre-generated and you don’t want to bother about showing skeleton for non-pre-generated pages then you will use fallback = blocking

export async function getStaticPaths() {

  // generate all paths
  const paths = getPaths()

  return { paths, fallback: 'blocking' }
}

Now when any user requests for a page they will not see anything but a blank page (or loader). The server will only respond after getting the appropriate props in the background.

Final Words Try to understand the different values of fallback property in order to take advantage of the full power of Next.js’s static generation.

That’s it for today. Have a great day!

Profile Image

Who I am

Hi, I amMohammad Faisal, A full-stack software engineer @Cruise , working remotely from a small but beautiful country named Bangladesh.

I am most experienced inReactJS,NodeJS andAWS

Buy Me a Coffee Widget