๐ On-Demand ISR with Next.js and GitHub Webhooks
Next.js introduced Incremental Static Regeneration (ISR) to allow pages to be statically generated at runtime. With On-Demand ISR, you get even finer control โ you can revalidate a page programmatically on demand rather than waiting for a revalidation time interval.
In this post, weโll walk through setting up On-Demand ISR with GitHub Webhooks, so that your site updates automatically whenever content is pushed to a GitHub repository.
๐ง What is On-Demand ISR?
Normally in ISR, you define a revalidate time in getStaticProps:
export async function getStaticProps() {
const data = await fetchData()
return {
props: { data },
revalidate: 60, // Rebuild every 60 seconds
}
}
With On-Demand ISR, you skip the timer and instead hit an API route manually to trigger regeneration:
await res.revalidate('/my-page')
This is especially useful for CMS-driven content or GitHub-based markdown blogs.
๐ ๏ธ Setup: GitHub Webhook + Next.js API Route
1. Create the Revalidation API Route
Create a file at pages/api/revalidate.ts:
// pages/api/revalidate.ts
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const secret = process.env.REVALIDATE_SECRET
if (req.query.secret !== secret) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
await res.revalidate('/blog')
return res.json({ revalidated: true })
} catch (err) {
return res.status(500).json({ message: 'Error revalidating' })
}
}
๐ก Note: Set
REVALIDATE_SECRETin your.env.localfile and on GitHub.
2. Update .env.local
REVALIDATE_SECRET=my_super_secret_token
3. Set Up GitHub Webhook
- Go to your GitHub repo > Settings > Webhooks.
- Click Add webhook.
- Set the Payload URL to your deployed API route (e.g.,
https://yoursite.com/api/revalidate?secret=my_super_secret_token). - Set the Content type to
application/json. - Choose events like
pushorcontent change. - Save the webhook.
โ Testing the Setup
Push a change to your GitHub repo (e.g., edit a blog post). GitHub should:
- Hit your webhook.
- Trigger the API route.
- Regenerate the page
/blog.
You can also manually test via:
curl -X GET "https://yoursite.com/api/revalidate?secret=my_super_secret_token"
๐งช Bonus: Revalidate Specific Pages
You can pass a slug or path in the webhook payload and revalidate specific pages:
await res.revalidate(`/blog/${slug}`)
๐ฏ Final Thoughts
On-Demand ISR lets you combine the performance of static sites with the flexibility of dynamic updates. By connecting GitHub Webhooks, youโve automated the workflow: content updates in your repo instantly reflect on your site.
Got a markdown blog or headless CMS? Pair it with this setup, and you're good to go!
