Static HTML Export
output: 'export' tells Next.js to produce a fully static bundle: plain HTML, CSS, and JavaScript files in an out/ directory, with no Node.js server involved at runtime at all. The result can be served by literally any static file host — an S3 bucket, GitHub Pages, Netlify, a CDN, or a plain nginx container — because there is nothing left to execute on the server.next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
}
export default nextConfigBuild the static export
npm run build # static files are written to ./out
Server Actions — they need a server to receive the mutation request.
Dynamic Route Handlers — a
route.tsthat reads request data or hits a database per request has nothing to run on.Incremental Static Regeneration (ISR) — there is no server process to revalidate a page on a schedule or on demand after the export exists.
The Image Optimization API —
next/imagefalls back to serving the original, unoptimized file, or needs a third-party loader configured.Middleware — it runs on every request on a server; a static host has no request lifecycle to hook into.
Dynamic rendering / cookies / headers — pages that need per-request data (like reading a cookie during render) cannot be exported as static HTML.
What still works
Still works | Does not work |
|---|---|
Static Server Components ( | Server Actions |
Client Components and client-side interactivity | Dynamic Route Handlers (per-request logic) |
Client-side data fetching ( | Incremental Static Regeneration |
| The built-in Image Optimization API |
Static Route Handlers that return the same response every time | Middleware |
| Cookie- or header-based dynamic rendering |
Where static export fits
Static export is the right tool when the entire site is knowable at build time — marketing pages, documentation, a blog, a portfolio — and you want the absolute simplest, cheapest hosting story: upload a folder to a CDN and you are done. It is the wrong tool the moment any page needs to run logic per request; for that, a self-hosted Node.js server or a platform like Vercel is required.
generateStaticParams — the export process visits each one at build time and writes it out as its own HTML file. What is not supported is generating a page for a path on demand after the export has already happened.