Статическая и динамическая отрисовка
Next.js может подготовить HTML страницы один раз при сборке — это статическая отрисовка. Или отрисовывать страницу заново для каждого посетителя — это динамическая отрисовка. Статическая страница отдаётся мгновенно, динамическая всегда показывает актуальные данные. Next.js выбирает режим сам, глядя на код страницы.
Как Next.js выбирает
Страница становится динамической, если использует что-то, известное только в момент запроса:
| Что использует страница | Режим |
|---|---|
Только свои данные и fetch | Статический |
cookies() или headers() | Динамический |
Свойство searchParams | Динамический |
export const dynamic = 'force-dynamic' | Динамический |
Динамический сегмент без generateStaticParams | Динамический |
Как узнать режим
Соберите проект:
npm run buildВ конце терминал покажет таблицу маршрутов. Значок ○ означает статическую страницу, ƒ — динамическую, ● — статические страницы, собранные по списку параметров. Всё сказанное в этом уроке относится к обычной модели Next.js 16; с включёнными Cache Components правила другие, о них — в отдельном уроке.
generateStaticParams
Страница статьи app/posts/[slug]/page.tsx по умолчанию динамическая: Next.js не знает заранее, какие бывают slug. Функция generateStaticParams сообщает этот список:
// app/posts/[slug]/page.tsx
import { notFound } from 'next/navigation';
import { getPost, getPosts } from '@/lib/posts';
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map((post) => ({ slug: post.slug }));
}
export default async function PostPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = await getPost(slug);
if (!post) notFound();
return <h1>{post.title}</h1>;
}Функция возвращает массив объектов, по одному на страницу; ключ совпадает с именем папки. После npm run build в таблице появится ● и адреса /posts/hello-nextjs и /posts/server-components — их HTML готов заранее.
Новые статьи после сборки
Статья, добавленная после сборки, всё равно откроется: Next.js отрисует её при первом запросе и сохранит. Если такие адреса должны давать 404, добавьте в файл страницы:
// app/posts/[slug]/page.tsx (фрагмент)
export const dynamicParams = false;Принудительно динамическая страница
Если страница должна показывать свежие данные из базы на каждый запрос, объявите это явно:
// app/posts/page.tsx (фрагмент)
export const dynamic = 'force-dynamic';Тогда /posts перестанет собираться заранее и в таблице сборки получит значок ƒ. Мягкий вариант — export const revalidate = 60 из урока о кешировании.
Частая ошибка
Читать список статей из базы на странице без этих настроек и удивляться, что на сервере новые статьи не появляются. Страница без динамических функций собралась статически, и её HTML не меняется. Выберите явно: revalidate, dynamic = 'force-dynamic' или revalidatePath после изменения данных.