Published on June 8, 2020
What is Next.js Incremental Static (Re)Generation?
With these Next.js improvements, you can build your app as a static web app. But it can also (re)generate those static pages as needed. In a way, it's like putting a static cache in front of your server-side rendered(SSR) app.
So, you get the benefits of both SSR and static site generation(SSG).
Unlike a caching server, this is a built-in feature of Next.js, and you are in full control of how to manage those pages. You can use your existing deployment solution to get the full benefits. But if you deploy your app with Vercel, it will be much faster and smoother.
This is how Incremental Static Regeneration works. Start reading for more details.
I know you have a lot of questions, let's dive in.
Server Side Rendering (SSR)
One of the core selling points of Next.js is its ability to build Server Side Rendered apps. With that, you can generate pages at runtime. For example, let's say you are running a news website.
- You create a generic page like /news/[slug].js.
- If a user asks for a page like /news/covid19, Next.js will render it inside the server and send it to the user.
- This process applies even the user asks for the same page again, or it's a different page like /news/global-warming
Have a look at this example:
import Link from 'next/link'
export default function NewsPage({slug, updatedAt}) {
const timeString = new Date(updatedAt).toLocaleTimeString();
return (
<div className="container">
<h1>News: {slug}</h1>
<p>This is a news about: {slug}</p>
<div className="meta">
Updated at <span className="time">{timeString}</span>
</div>
<div>
<Link href="/"><a>Home</a></Link>
</div>
</div>
)
}
NewsPage.getInitialProps = async ({query}) => {
return {
slug: query.slug,
updatedAt: Date.now()
}
};
It's a simple page served via SSR. It contains the time the page has generated.
Try to follow these steps in the above web site:
- Click the page "Covid 19".
- Remember the time it was updated.
- Go back.
- Come back again.
- Check the time now.
Q: Do this multiple times. What was your experience?
( Click to answer )
Let me ask you some questions.
Q: What is a benefit of SSR?
( Click to answer )
Q: Is there any problem(s) with SSR?
( Click to answer )
Static Site Generation (SSG)
With the static site generation, we generate pages at build time into static HTML. Then, when a user asks for a page, Next.js can quickly deliver the page. (There's no on-demand page generation process.)
After you build the app, you will get a set of HTML files and related assets. Since there's no need for a Node.js server, you have more options to deploy your app.
Here's a Next.js page of a simple news portal app built with SSG:
import Link from 'next/link'
export default function NewsPage({slug, updatedAt}) {
const timeString = new Date(updatedAt).toLocaleTimeString();
return (
<div className="container">
<h1>News: {slug}</h1>
<p>This is a news about: {slug}</p>
<div className="meta">
Updated at <span className="time">{timeString}</span>
</div>
<div>
<Link href="/"><a>Home</a></Link>
</div>
</div>
)
}
export async function getStaticPaths() {
return {
paths: [
{params: {slug: 'covid19'}},
{params: {slug: 'globalwarming'}},
],
fallback: false
}
}
export async function getStaticProps({params}) {
return {
props: {
slug: params.slug,
updatedAt: Date.now()
}
}
}
Try to follow these steps in the above web site:
- Click the page "Covid 19".
- Remember the time it was updated.
- Go back.
- Click "Covid 19" again
- Check the updated time now.
Q: Do this multiple times. What was your experience?
( Click to answer )
With static apps,
- Users can access pages very quickly
- Server resource usage is much less compared with an SSR app.
Q: Is there any problem(s) with SSG?
( Click to answer )
Next.js Improvements for Static Site Generation
As we discussed, SSG apps perform really well after we deployed them. It saves server resources, and users can access pages very quickly. But it has two main disadvantages:
- It takes more time to build the app
- To add new content or update existing, we need to rebuild the app
That's where these improvements are going to help us.
Incremental Static Generation - Fallback Mode
Just like in SSG, we can generate a set of pages at the build time. But it can also generate new pages on-demand as needed.
Let me give you an example:
- Here's a route for a typical news portal: /news/[slug]
- We can generate pages via SSG for /news/covid19 and /news/global-warming
- But it can create pages for a new slug like news/so-srilanka in the server.
With this, we don't need to build all the pages at build time. That will reduce the build time.
Incremental Static REgeneration
Sometimes pages contain dynamic content, or we need to fix a typo. With this regeneration mode, Next.js can rebuild these pages on-demand as it gets requests. But unlike SSR, they do not generate on every page request. You can set a timeout called unstable_revalidate in seconds.
With that, Next.js can regenerate these pages after the timeout in the background. But if there are no requests to a given page, there's no regeneration.
With this, we can update pages at runtime, just like in an SSR app.
As you can see, these improvements bring positive things from both SSR and SSG.
Let me show you an example:
import Link from 'next/link'
export default function NewsPage({slug, updatedAt}) {
const timeString = new Date(updatedAt).toLocaleTimeString();
return (
<div className="container">
<h1>News: {slug}</h1>
<p>This is a news about: {slug}</p>
<div className="meta">
Updated at <span className="time">{timeString}</span>
</div>
<div>
<Link href="/"><a>Home</a></Link>
</div>
</div>
)
}
export async function getStaticPaths() {
return {
paths: [
{params: {slug: 'covid19'}},
{params: {slug: 'globalwarming'}},
],
fallback: true
}
}
export async function getStaticProps({params}) {
// You can fetch external data here
return {
props: {
slug: params.slug,
updatedAt: Date.now()
},
unstable_revalidate: 10
}
}
Make your attention to
fallback
and unstable_revalidate
.We generated the following two pages in the build time:
- /news/covid19
- /news/globalwarming
(We provide this information via the getStaticPaths function)
But it can also generate new pages like /news/srilanka as needed, because we have set fallback to true. Then we need to write our getStaticProps function to fetch related data in the runtime as well.
In our example app, we don't fetch any external data. In a real-world app, you might need to talk to a CMS, external API, or to a database.
Try to follow these steps in the above web app:
- Click the "Sri Lanka" page
- Wait until it asks you to reload the page
- Remember the updated time
- Reload it again
- Wait for a second and Reload it again
Q: What was your experience?
( Click to answer )
This is what's happening behind the scenes:
- In the first reload, Next.js sends you the old version of the page.
- But it starts to regenerate the page in the background.
- In the next reload, you will get the newly built page.
Yes, you have to reload the page twice to get the updated version. But if multiple users are accessing the page, it's not problem at all.
This is very similar to how stale-while-revalidate HTTP header works.
(Next.js uses that header too.)
(Next.js uses that header too.)
Q: Why I asked you to load this "Sri Lanka" page explicitly?
( Click to answer )
Now you have a much better understanding of what Next.js iSSG means and how you can get the real benefit of it.
Clone this example repository and play with it.
There are many things to discuss about "building a modern app" with Next.js. I am creating more content like this and publish once every week.
Subscribe to get these posts right into your inbox.