Course
ISR
Next.js Mastery: From Fundamentals to Full-Stack
Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.
ISR
Concept
ISR stands for "Incremental Static Regeneration".
Imagine you're running a blog. You want your pages to load fast, but you also want to show up-to-date information like the number of likes on each post. This is where Incremental Static Regeneration (ISR) comes in handy.
The Problem
Traditional static websites are fast, but they can't easily show changing data. Dynamic websites can show fresh data, but they might be slower. ISR gives us the best of both worlds.
How ISR Works
- First Visit: When someone visits your blog post for the first time (or after a while), they see a pre-built version of the page. This loads very quickly.
- Behind the Scenes: While the visitor is reading, Next.js starts creating a new version of the page with the latest data (like updated like counts).
- Next Visits: The next time someone visits this page, they'll see the newer version with the updated information.
- Repeat: This process keeps happening, so your pages stay relatively fresh without slowing down.
Why It's Useful
- Speed: Pages load fast because they're pre-built.
- Freshness: Content updates regularly without rebuilding the entire site.
- Efficiency: Your server doesn't have to work hard for every single visit.
In Simple Terms
Think of ISR like a restaurant menu. The menu is printed (static) so it's quick to hand out. But every so often, the restaurant prints a new batch with updated prices or dishes. Customers always get a menu quickly, and it's usually up-to-date, even if not always 100% current.
ISR in Next.js does the same for your website: fast delivery of content that's updated regularly but not in real-time.
Implementing ISR
Next.js supports ISR, and it's simple to use. You just need to add a
revalidate
property in getStaticProps
. Here's an example based on the SSG code:// pages/post/[id].jsimport { useRouter } from 'next/router'
export default function Blog({ post }) { const router = useRouter()
// If the page is not yet generated, this will be displayed // initially until getStaticProps() finishes running if (router.isFallback) { return <div>Loading...</div> }
return ( <> <header>{post.title}</header> <main>{post.body}</main> <footer>Last updated: {new Date().toLocaleString()}</footer> </> )}
export async function getStaticPaths() { const res = await fetch('https://jsonplaceholder.typicode.com/posts') const posts = await res.json() const paths = posts.slice(0, 10).map((post) => ({ params: { id: String(post.id) }, })) return { paths, fallback: 'blocking' }}
function getRandomInt(max) { return Math.floor(Math.random() * max);}
export async function getStaticProps({ params }) { // Use params.id to fetch the correct post const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`) const post = await res.json() // Simulate dynamic data by adding a random number of likes post.likes = getRandomInt(100)
return { props: { post }, revalidate: 10 // Revalidate every 10 seconds }}
revalidate
indicates how many seconds should pass before updating the page when a request occurs.
Here's how this implementation works with ISR:
- The first 10 blog posts are pre-rendered at build time.
- When a request comes for a post that wasn't pre-rendered, Next.js will generate it on-demand (because of
fallback: 'blocking'
). - Every 10 seconds (at most), if a new request comes in, Next.js will regenerate the page in the background.
- The random "likes" count and the updated timestamp in the footer will show that the page content can change on each regeneration.
To test ISR functionality, you need to build the production version and run the production server:
next build # or npm run buildnext start # or npm run start
This implementation demonstrates ISR by:
- Pre-rendering some pages
- Generating non-pre-rendered pages on-demand
- Periodically updating pages with fresh data
Hybrid Approach
Next.js is flexible in how it renders pages, allowing for a hybrid approach that combines different rendering methods. Here's a breakdown:
- Automatic Mode Selection
- Next.js automatically chooses the rendering mode for each page.
- You don't need to explicitly declare the mode.
- Rendering Modes
- Server-Side Rendering (SSR): Used when a page has
getServerSideProps
.
- Static Site Generation (SSG): Default for pages without
getServerSideProps
.
- Client-Side Rendering (CSR): Always includes some static HTML, even if minimal.
- Hybrid Example: SSG + CSR Let's look at a practical example that combines Static Site Generation with Client-Side Rendering:
// pages/postList.jsimport React, { useState } from 'react'
export default function Blog({ posts }) { const [data, setData] = useState(posts)
return ( <> <button onClick={async () => { const res = await fetch('https://jsonplaceholder.typicode.com/posts') const posts = await res.json() setData(posts.slice(10, 20)) }}> Change Batch </button> <ul> {data.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </> )}
export async function getStaticProps() { const res = await fetch('https://jsonplaceholder.typicode.com/posts') const posts = await res.json() return { props: { posts: posts.slice(0, 10), }, }}
How it works:
- Initial render: The page is pre-rendered with the first 10 posts (SSG).
- User interaction: Clicking "Change Batch" fetches new data client-side (CSR).
This hybrid approach offers a fast initial load with SSG, while maintaining dynamic interactivity through CSR.
Summary
Congratulations on completing this content!
In this article, we briefly reviewed the four rendering modes under Next.js Pages Router. However, in the App Router, due to the shift to using React Server Components, these concepts have been de-emphasized in favor of concepts like "server components" and "client components". How do these rendering modes relate to and differ from the so-called "server components" and "client components"? We encourage you to continue learning to find out.