Next.js
I. Next.js Fundamentals
1. Introduction to Next.js
2. Next.js vs React
3. Project Setup
4. Folder Structure
5. Pages and Routing
6. Link and Navigation
7. Static Assets
8. CSS and Styling
II. Routing, Data & Rendering
9. Dynamic Routing
10. API Routes
11. Data Fetching Basics
12. getStaticProps
13. getServerSideProps
14. Incremental Static Regeneration
15. Rendering Strategies
16. Image Optimization
III. Advanced Next.js & Performance
17. Middleware
18. Authentication Basics
19. Authorization
20. Environment Variables
21. Performance Optimization
22. SEO with Next.js
23. Internationalization
24. Error Handling
IV. Projects, Deployment & Best Practices
25. Next.js Best Practices
26. Folder and Code Organization
27. Testing Next.js Apps
28. Security in Next.js
29. Next.js Interview Questions
30. Mini Project – Blog
31. Mini Project – Dashboard
32. Mini Project – Ecommerce
33. Mini Project – API Integration
34. Next.js Case Study
35. Real-World Use Cases
36. Project Planning
37. Final Project
38. Deployment with Vercel
39. Course Review
40. Career Roadmap
LESSON 14
NewsWave homepage with trending articles? ISR every 5 minutes. User dashboard with personal notifications? SSR or CSR. Legal pages that change twice per year? Pure SSG. Live chat messages? CSR only.
Production apps integrate this logging with services like Datadog or LogRocket. You'll spot patterns like "revalidation takes 5 seconds on weekday mornings" that help you optimize your infrastructure. The NewsWave team discovered their image processing API caused slowdowns during peak traffic hours.
Incremental Static Regeneration
Build pages that stay fast forever using ISR to regenerate static content on demand without full rebuilds.
Static pages break when content changes frequently. You build your site with Monday's data. By Tuesday, users see stale information. Rebuilding everything takes forever. Incremental Static Regeneration fixes this completely. ISR lets you regenerate specific pages after they're built. Think of it like spot-cleaning a house instead of deep-cleaning every room. Your pages stay static and fast, but they update when needed. UnlikegetServerSideProps which runs on every request, ISR pages serve instantly from cache. They regenerate in the background when the cache expires. Users never wait. The NewsWave team needs this for article pages that must stay fast but show accurate view counts.
How ISR Actually Works
ISR combines the best parts of static and dynamic rendering. When someone requests a page, Next.js checks if it's time to regenerate. If not, they get the cached version instantly. If yes, they still get the cached version, but Next.js regenerates a fresh copy in the background. The regeneration happens after the user leaves. The next visitor gets the updated version. This pattern is called "stale-while-revalidate" — serve stale content while building fresh content behind the scenes. Traditional static sites rebuild everything when one article changes. That might mean regenerating 10,000 pages because you fixed a typo. ISR regenerates only the changed page. Your build stays under one minute instead of taking an hour.SSG vs ISR Timeline
SSG: Build (all pages) → Deploy → Stale forever
ISR: Build (all pages) → Deploy → Regenerate individually → Always fresh
ISR: Build (all pages) → Deploy → Regenerate individually → Always fresh
Adding ISR to getStaticProps
ISR requires just one line added togetStaticProps. The revalidate property tells Next.js how many seconds to cache the page. After that time, the next visitor triggers regeneration.
// pages/articles/[slug].js - NewsWave article page with ISR
export async function getStaticProps({ params }) {
// Fetch article data exactly like normal SSG
const article = await fetch(`https://api.newswave.com/articles/${params.slug}`)
.then(res => res.json())
return {
props: {
article
},
revalidate: 60 // Regenerate every 60 seconds maximum
}
}// The article component receives fresh data automatically
export default function Article({ article }) {
return (
<div style={{ maxWidth: '800px', margin: '0 auto', padding: '20px' }}>
<h1>{article.title}</h1>
<p>Views: {article.viewCount}</p>
<p>Last updated: {new Date().toLocaleTimeString()}</p>
</div>
)
}localhost:3000/articles/breaking-ai-news — NewsWave
What just happened?
The
revalidate: 60 tells Next.js this page expires after 60 seconds. The first visitor after expiration gets the cached version but triggers regeneration. The next visitor gets fresh data. Try this: refresh multiple times to see the timestamp change after the revalidation window.ISR Rendering Flow Visualization
Understanding ISR timing prevents confusion. Here's exactly what happens from the user's perspective and Next.js's perspective during the regeneration cycle.First 60 Seconds
All visitors get cached version instantly. No regeneration triggered. Lightning fast responses.
After 60 Seconds
Next visitor gets stale cache but triggers background regeneration. Still fast.
Regeneration Complete
Fresh version replaces cache. All future visitors get updated content until next expiration.
Error Handling
If regeneration fails, visitors keep getting the last successful version. No broken pages.
On-Demand ISR with API Routes
Waiting for revalidation time feels silly when you know content changed. On-demand ISR lets you regenerate specific pages immediately when content updates. Perfect for NewsWave when editors publish breaking news. Next.js providesres.revalidate() to trigger regeneration from API routes. Call it after updating your database. The page rebuilds instantly instead of waiting for the next visitor after expiration.
// pages/api/revalidate.js - Trigger regeneration on demand
export default async function handler(req, res) {
// Verify this request came from your CMS or admin panel
if (req.query.secret !== process.env.REVALIDATE_TOKEN) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
// Regenerate the specific article page that was updated
await res.revalidate(`/articles/${req.query.slug}`)
return res.json({ revalidated: true })
} catch (err) {
return res.status(500).send('Error revalidating')
}
}// Your CMS webhook calls this after content updates
// POST /api/revalidate?secret=your-token&slug=breaking-ai-news
// This immediately regenerates /articles/breaking-ai-news
// Multiple pages can be revalidated in one request
export default async function handler(req, res) {
if (req.query.secret !== process.env.REVALIDATE_TOKEN) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
// Regenerate article page and category page
await res.revalidate(`/articles/${req.query.slug}`)
await res.revalidate(`/category/tech`) // If it was a tech article
return res.json({ revalidated: true, pages: 2 })
} catch (err) {
return res.status(500).send('Error revalidating')
}
}Terminal
$ curl "http://localhost:3000/api/revalidate?secret=your-token&slug=breaking-ai-news"
{"revalidated": true, "pages": 2}
✓ Article page regenerated instantly
What just happened?
The webhook triggers immediate regeneration without waiting for expiration. Your CMS calls this endpoint after editors save changes. Readers see updates within seconds instead of minutes. Try this: set up a simple form that calls your revalidate endpoint to test manual regeneration.
ISR Error Handling and Fallbacks
ISR regeneration can fail. Your API might be down. Your database might timeout. Next.js handles this gracefully by serving the last successful version, but you should implement proper error handling for production apps. Thefallback property in getStaticPaths becomes crucial with ISR. When someone requests a page that wasn't pre-built, Next.js can generate it on-demand and add it to the ISR cache.
// pages/articles/[slug].js - Complete ISR with error handling
export async function getStaticPaths() {
// Pre-build only popular articles at build time
const popularSlugs = ['breaking-news', 'tech-update', 'market-report']
const paths = popularSlugs.map(slug => ({
params: { slug }
}))
return {
paths,
fallback: 'blocking' // Generate missing pages on first request
}
}export async function getStaticProps({ params }) {
try {
// Attempt to fetch article data
const response = await fetch(`https://api.newswave.com/articles/${params.slug}`)
if (!response.ok) {
// Article doesn't exist or API is down
return {
notFound: true // Shows 404 page instead of broken page
}
}
const article = await response.json()
return {
props: { article },
revalidate: 300 // 5 minutes - balance freshness with API load
}
} catch (error) {
// Network error, API timeout, etc.
console.error('ISR generation failed:', error)
return {
notFound: true // Fail gracefully rather than show broken page
}
}
}localhost:3000/articles/nonexistent-article — NewsWave
What just happened?
ISR error handling prevents broken pages when APIs fail. The
notFound: true return shows a clean 404 instead of a broken page. The fallback: 'blocking' generates missing pages on-demand. Try this: intentionally break your API URL to see graceful error handling.Choosing the Right Revalidation Time
Revalidation timing balances freshness against server load. Set it too low and you're essentially doing SSR. Set it too high and content stays stale too long. Real-world apps use different times for different content types. NewsWave breaking news needs 30-second revalidation. Regular articles can wait 10 minutes. Author bio pages might revalidate daily. Category pages with dozens of articles could regenerate hourly. Match your revalidation frequency to how often your content actually changes.High Frequency (30-300s)
Breaking news, stock prices, sports scores, live events, trending topics
Medium Frequency (5-60min)
Article pages, product listings, user-generated content, comments
Low Frequency (1-24hrs)
Author profiles, company pages, documentation, static marketing content
On-Demand Only
Legal pages, privacy policies, terms of service, rarely-updated content
// Different revalidation strategies for NewsWave content types
export async function getStaticProps({ params }) {
const { contentType, slug } = params
let revalidateTime
// Match revalidation to content update frequency
switch (contentType) {
case 'breaking':
revalidateTime = 30 // Breaking news updates every 30 seconds
break
case 'articles':
revalidateTime = 600 // Regular articles every 10 minutes
break
case 'authors':
revalidateTime = 86400 // Author pages daily
break
default:
revalidateTime = 3600 // Default to hourly
}
const content = await fetchContent(contentType, slug)
return {
props: { content },
revalidate: revalidateTime
}
}Terminal
$ npm run build
✓ Breaking news: revalidate every 30s
✓ Articles: revalidate every 10min
✓ Authors: revalidate daily
✓ ISR configured for optimal performance
ISR vs Other Rendering Strategies
ISR isn't always the best choice. Sometimes you need real-time data on every request. Sometimes static generation without regeneration works fine. Understanding when to use ISR prevents overengineering simple scenarios.| Strategy | Use When | Performance | Freshness |
|---|---|---|---|
| SSG | Content never changes | Fastest | Stale after build |
| ISR | Content changes occasionally | Fast | Eventually fresh |
| SSR | Content changes frequently | Slower | Always fresh |
| CSR | User-specific data | Slowest initial load | Real-time |
Common ISR Mistake
Using ISR for user-specific content like dashboards or shopping carts. ISR caches the same content for all users. Personal data should use SSR or CSR instead.
ISR Performance Monitoring
ISR regeneration happens in the background, making it hard to debug issues. Next.js doesn't tell you when regeneration fails. You need to implement monitoring to catch problems before users notice stale content. Build simple logging to track regeneration success and failure rates. Monitor your API response times during regeneration. Set up alerts when revalidation consistently fails. This prevents scenarios where your ISR pages serve week-old content because your API has been down.// pages/api/revalidate-with-logging.js - Monitor ISR health
export default async function handler(req, res) {
const startTime = Date.now()
try {
await res.revalidate(`/articles/${req.query.slug}`)
// Log successful revalidation
console.log({
type: 'revalidation_success',
slug: req.query.slug,
duration: Date.now() - startTime,
timestamp: new Date().toISOString()
})
return res.json({ revalidated: true })
} catch (error) {
// Log failed revalidation for monitoring
console.error({
type: 'revalidation_error',
slug: req.query.slug,
error: error.message,
duration: Date.now() - startTime,
timestamp: new Date().toISOString()
})
return res.status(500).json({ error: 'Revalidation failed' })
}
}Terminal
{"type": "revalidation_success", "slug": "ai-news", "duration": 245}
{"type": "revalidation_success", "slug": "tech-update", "duration": 189}
{"type": "revalidation_error", "slug": "broken-article", "error": "API timeout"}
✓ ISR health monitoring active
Quiz
1. What happens when a NewsWave reader visits an article page after the ISR revalidation time has expired?
2. How do you configure a NewsWave category page to regenerate every 5 minutes using ISR?
3. What's the best way to regenerate a NewsWave article page immediately after an editor publishes updates?
Up Next: Rendering Strategies
Compare all Next.js rendering approaches and learn when to use SSG, ISR, SSR, or CSR for different parts of your application.