Does Netlify support Incremental static regeneration of Next.js? Do we need to have special plugins or build commands for that to work?
Welcome to the Community As I finished writing the below post, please know that it’s written for you and whoever else may come looking for insight on the question of Next.js ISR. I may go deeper than you intended, but I think someone in the future may appreciate that
Phew, a bit of a complex question here! Next.js’s ISR feature, I believe, was developed with a dynamic back-end in mind (WordPress, for example) where the content on an individual endpoint rarely changes and therefore the view can be made static. When the data does change, that static view can be regenerated on the fly in the background then seamlessly ‘made live’ once it’s done.
FYI, “Statify” = “Static-ify”, or to take content, hold onto it, and serve it to everyone the same, in a ‘static’ way
To me, this fits great for something like a blog. Posts are rarely made so there’s no sense in having a web server generate the same HTML for every request when the content doesn’t change per request (that’s a lot of horsepower for the same stuff all the time!) - so Next can sit in the middle, statify that content, and serve it as a purely static view. Then when the underlying content changes (a new blog post is made) Next can recognize that and generate the new version of the static content, then swap it in once it’s built.
I want to point out, this is a fundamentally different model of Next.js working than how it does on Netlify in almost all cases. This model requires an active and running Next.js server in a hosted environment. It’s quite different than Next operating as a SSG and producing static files then the process ending (where those resulting files are then uploaded to Netlify Edge and served… statically).
Now, that all said, Next’s ISR functionality is actually just a smaller scale version of what Netlify’s whole platform is somewhat built on. Instead of having the Next process hold static files and regenerate them on an as-needed basis, Netlify’s whole platform holds static files, and you can use a build/update hook to just re-build your whole site when new content is updated. The difference is that Netlify’s process doesn’t require a hosted Node.js process running to manage these updates, you just tell the platform to rebuild things via the Netlify build hooks.
So, in the example case (and these are real; lots of people do both of the following) - Let’s say you have WordPress+Next in architecture A, and WordPress+Gatsby in architecture B (this could also be Next.js running in SSG mode, but for the sake of confusion, we’ll just say WordPress+Gatsby).
Arch.A - Next.js is an active, hosted process sitting ‘in front’ of WordPress and intercepting requests for the
/blog path. We’ve programmed Next to statify the
/blog path and so when User A requests
/blog for the first time since process start-up, Next generates the content by hitting the WordPress back end and hydrating a template, then passing that view back to User A. When User B comes around, Next doesn’t have to hydrate a template or anything, it just saved the content it served to User A (statify’ing it) and passes it to User B much quicker. If the
/blog content updates, Next can regenerate then re-statify that content in real time and continue on its way. It’s a cool process for getting static speed from content that updates often and has other necessities.
Arch.B - Gatsby is a static site generator that pulls content from WordPress at build time then generates a React SPA as static files that get served through Netlify. In this case, User A and User B’s requests will generally result in the same content and be served at the speed of static. All requests are essentially handled the same and all performance is static across the board. When a new blog post is created, WordPress pokes Netlify with a web-hook and essentially says “hey I posted a new blog post, rebuild the Gatsby site” - to which Gatsby pulls in the new content, generates the site, and Netlify pushes it live for everyone in a couple minutes (depending on build time.
There are a lot of tradeoffs here. Arch.A requires running, maintaining, and scaling a Node.js process on the public internet for the sake of rendering your content. That’s a real overhead! But it has some pros - some of your content can be fully dynamic (generated per request) which works well for some industries / content types, and Next can generally regenerate individual static routes faster than it takes to rebuild the whole static site in the Gatsby case. That’s a plus too if your’e constantly pushing out new content.
Conversely, Arch.B IMO is going to be a bit more performant since there’s no hosted process and everything revolves around static file delivery, but your latency between making a new blog post and it being ‘live’ may be a bit higher since you have to wait for the build to complete. So both methods are great and have their uses, but the point is:
I don’t think they really co-exist. You can’t run a hosted Node.js process on Netlify, and trying to get Next.js running in some strange way on Netlify Functions would be painful and probably not worth the trouble. They’re just different architectures. I hope that at least gives you an overview to some of the mechanics and why they’re different Happy to explain further details if some of that doesn’t fully make sense!
One last bit I’ll add here at the bottom is that there is growth in a cool area for helping the build latency get faster, meaning the value proposition of the fully-static path is getting stronger. Gatsby and Next are both working on allowing their static site builds to re-use parts of the previous build and only build the new stuff when the site rebuilds. This concept isn’t far off from ISR at a high level but requires very different componentry. I won’t get into it much, but if the Gatsby build in Arch.B above only has to rebuild the pages that actually changed (e.g. a single new blog post) then the build time will be dramatically faster. That’s a great thing. Here’s an article Jason wrote on Gatsby’s new support for incremental builds. I believe Next.js supports this too but it’s tougher to dig through docs and find it because Next.js runs in so many ways (including as a hosted process with ISR) that it’s tricky to find specific docs. I’d encourage some research from anybody looking for more
Hope all of that helps!
I don’t even know what to say, @jonsully. That is an incredible detailed and helpful answer.
Sometimes I think I should just turn some of the longer stuff I write here into blog posts alas
Thank you for your detail explanation. That is very helpful. I am sure that will be beneficial to turn that into a blog post as well.