Next.js SSR vs. SSG & Incrementalism
By: Nate Jones
Tags: Nextjs, JavaScript, React, Server Side Rendering, Web Development

Thanks to Static Generation with data, we can now build out all of our blog post pages and routes at build time, which is great. What happens you write a new blog post? Everything was generated already at build time only, so you won’t see the new post if you refresh your browser. In this case, the best thing to do is rebuild the site, so the newest content becomes available. This might seem slightly annoying, but the content doesn’t change too frequently, and you can automate your build / deploy process for your blog.

The need to rebuild and deploy certainly begs the question, though — at what point is the content changing too quickly or growing too large in size to justify rebuilding your site all the time? Another factor to consider is which users can access various content? For the blog example, I assume it’s all totally public. But if there is some private, per-user data, we won’t want to pre-render everything with user data baked in. The next use case shows off a couple more SSG tricks in Next.js to handle more complexity.

Use Case 3: Growing E-commerce Site

This example is based off of this blog post from Vercel (the people who make Next.js). I’ll summarize but I recommend going through their full post as well.

We handled the pre-rendering strategy for your blog site with Static Generation with Data, above. Now, you have a rapidly growing E-commerce site. Thousands of products will be added this week, and the existing product listings will change somewhat frequently (pricing, inventory, etc.).

Let’s focus first on the page that lists the products (e.g. /products ), as well as the individual product pages (e.g. /products/1 ). What happens if we try to apply the Static Generation with data technique?

We’ll hit an issue as products are added to the site. We would have to rebuild the site very frequently, and it would take a long time because we’d be statically generating thousands of product pages. This is infeasible. Similarly, we’ll have an issue as products change. Again, we would have to rebuild the site to reflect a product change to customers. Also infeasible.

We want to make sure customers see the newest data so they can buy products. Should we finally use SSR to ensure data is up to date on each request??

As it turns out, probably not! Next.js has a concept called Incremental Static Generation that helps dynamic sites like our E-commerce store stay in the world of Static Generation (Next.js does everything it can to help us use SSG!). As I’ve been working more and more with Next.js, I’ve found this to be some of the coolest stuff.

Case 1: Add Product Pages Over the Life of a Statically Generated Build

Let’s say we had statically generated our E-commerce site with 100 products. But now 1,000 new products will be listed this week. We can use a key called fallback inside of our call to getStaticPaths (I linked this above, too, but this is the case where you’re using SSG and automatically generating all paths and product pages at build time).

Normally, fallback will be false . This does what you’d expect — any path that hadn’t been generated at build time will return a 404. This is good because if someone goes to /products/<non-existent product_id> , a 404 is correct. However, you can unlock some special behavior if fallback is set to true . Check out the official fallback: true docs.

With true , a 404 won’t be returned for an unknown path. Instead, you’ll get indication from Next that you should display a “Fallback” page (essentially a loading page). Meanwhile, the server will lazily generate the appropriate page for the user. Here’s the workflow:

I add a product to the site with a new id of 5000 A user tries to go to the page /products/5000 , but it doesn’t exist quite yet (of course not, because I just added the product) The browser will display a Fallback / Loading page for the user (no error or anything like that) The server generates the HTML page for product 5000, and then adds 5000 to its set of known paths (now product 5000’s page can be cached in CDN) The user will now see the product page instead of the Fallback For all future requests for this product during the lifetime of this deployment, product 5000 is all set to go — the work just needed to be done once, lazily!

Case 2: Update Product Pages Over the Life of a Statically Generated Build

This case is even easier in Next.js. This one is called Incremental Static Regeneration, since this is all about re-generating a page periodically after the initial build.

All you need to do is add a key called revalidate in the call to getStaticProps . For example, revalidate: 60 (60 seconds) will have the following workflow: