Three ways the same page can reach a browser
- Static — the HTML is built when you deploy. A visitor gets a file that already exists.
- Server-rendered — the HTML is built when the visitor asks, per request, on a running server.
- ISR — static, but with an expiry. After the interval you set, the next visitor triggers a
rebuild in the background and subsequent visitors get the fresh version.
The important thing, and the thing tutorials tend to bury: this is a per-page decision. A single Next.js project can serve a static marketing page, a dashboard rendered per request, and a product page on a five-minute ISR window. There is one exception, and it is a big one, covered further down.
This is also the decision underneath the framework argument. If you are still at the stage of choosing between Next.js and plain React, it is the same question one level up: who renders the page.
The two questions that decide it
Go through your routes and ask two things about each one: is this page the same for everyone, and how stale is it allowed to be? Those two answers land you on one of the three, every time.
- Homepage, services, about — same for everyone, and as stale as your last deploy is fine.
Static. - Blog listing and posts — same for everyone, should update when you publish. Static if you
rebuild on publish, ISR if you would rather not. - Product page with live stock — same for everyone, but a few minutes stale is acceptable.
ISR. - Account page, dashboard, cart — differs per visitor. Server-rendered.
The pattern worth noticing: "differs per visitor" is the only answer that forces a server, and far fewer pages need it than people assume. A page that shows a logged-in name in the header is not a per-visitor page — that name can be fetched in the browser after a static page has already loaded.
Most business sites turn out to be almost entirely the first case, which is why static is a better default than its reputation suggests.
Static is a stronger default than people expect
Nothing computes at request time, so nothing can be slow at request time. The file sits on a CDN. A traffic spike is a bandwidth question rather than a capacity one. There is no server to patch, and the attack surface at request time is close to nothing. It also matters most where connections are worst — on a patchy mobile network the difference between a file and a computed response is the whole experience.
The cost is that content changes require a rebuild. If your marketing site changes weekly, that is a non-issue. If it changes hourly, it is friction.
What a fully static export actually costs
This is the part written from experience rather than documentation.
Setting output: 'export' in next.config is not the same as most pages being static. It makes the entire project static and removes the server permanently. The build produces plain HTML and assets and nothing else runs.
What that takes away:
- API routes and server actions. There is no server. Form submissions have to go to a third-party endpoint or an external function.
- Middleware. No request-time redirects, no auth gate, no geo logic. Redirects move to your host's configuration.
- ISR. Content is as fresh as your last deploy, full stop.
- Image optimisation. Next's optimiser needs a server, so images ship as-is and you handle sizing and format yourself.
- Dynamic routes must be enumerable. Every path needs
generateStaticParams, and a route it cannot enumerate fails the build rather than degrading.
There is also a subtler consequence: content from a CMS is fetched at build time. Publishing an article changes nothing on the live site until someone rebuilds. That is fine when you know it and surprising when you do not.
None of this makes static export a bad choice. It makes it a deliberate one. For a marketing site with a CMS and a deploy hook, the trade is usually worth it — hosting is trivial, the site is fast everywhere, and there is nothing to keep running.
Just decide it at the start, because unwinding it later touches forms, redirects, images and deployment together.
When ISR is the right middle
ISR is under-used because it sounds like a compromise. It is closer to having both.
Good fits: a blog where publishing should appear without a deploy, listings that change through the day, anything where "up to five minutes old" is genuinely acceptable.
Two things to know. The first visitor after expiry may see the old version while the rebuild happens behind them — usually fine, occasionally not. And it needs a host that supports it; a plain static host does not.
When to render on the server
When the page is genuinely different per visitor. A dashboard, an account page, personalised pricing, anything reading a session.
The mistake worth avoiding is server-rendering pages that are identical for everyone, "to keep content fresh". That is paying for the same work on every request when it could have been done once at build, or on a schedule with ISR.
Read your build output
Next prints, for every route, how it was rendered. It is the fastest way to catch a page that was supposed to be static and quietly is not — usually because something in the tree reads a cookie or uses a dynamic function.
Look at it after any significant change. A route that flips from static to dynamic without anyone noticing is a performance regression that no test catches and no monitoring reports.
What to do next
Put your routes through the two questions above. It takes fifteen minutes and it usually shows that most of the site can be static, one or two pages need ISR, and only the logged-in area needs a server.
If you are choosing hosting at the same time, the same list decides that too — a fully static site can go almost anywhere, while ISR and server rendering constrain the options. More on deployment and hosting, or ask us what your project needs.



