Saltar al contenido
alex@galhardo:~

$ cd ../blog

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.

Pipeline from MDX file to CDN

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.

tsx
// 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.

ApproachResult
Redirect by Accept-Language in a proxyA function runs on every request
Locale in the URL onlyFully 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.

ts
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 ƒ.

text
├ ● /[locale]/blog/[slug]
│ ├ /en/blog/hello-world
│ └ /pt-br/blog/hello-world

If a route shows ƒ, something in its tree read the request.