Keeping every page static in Next.js 16
· 1 min de lectura
Este post todavía no está traducido. Estás leyendo la versión en inglés.
This site has three languages and not one page is rendered on request. Here is the setup, and the two mistakes that quietly turn a static page into a dynamic one.

Tell the framework every param up front
A dynamic segment such as [locale] or [slug] is static only when the build knows all of its values.
// app/[locale]/blog/[slug]/page.tsx
export const dynamicParams = false
export function generateStaticParams() {
return locales.flatMap((locale) => getPosts(locale).map(({ slug }) => ({ locale, slug })))
}dynamicParams = false matters: without it, an unknown slug is rendered on demand instead of returning a 404.
Do not read the request
Reading cookies(), headers() or searchParams in a server component opts the whole route out of static
generation. The usual offender in a multilingual site is locale detection.
| Approach | Result |
|---|---|
Redirect by Accept-Language in a proxy | A function runs on every request |
| Locale in the URL only | Fully static |
English without a prefix, still static
The default language has no /en prefix. Instead of a proxy function, a rewrite in next.config.ts maps the
unprefixed path onto the [locale] segment. Rewrites are resolved by the CDN router.
async rewrites() {
return {
afterFiles: [
{ source: '/', destination: '/en' },
{ source: '/:path((?!en|pt-br|es|admin|api|_next).*)', destination: '/en/:path' },
],
}
}Check the build output
The build prints a table. Every public route should show ● (SSG) or ○ (static), never ƒ.
├ ● /[locale]/blog/[slug]
│ ├ /en/blog/hello-world
│ └ /pt-br/blog/hello-worldIf a route shows ƒ, something in its tree read the request.