Как работает Static Site Generation (SSG) в Next.js
SSG (Static Site Generation) это стратегия рендеринга, при которой HTML-страницы генерируются один раз на этапе сборки (next build). После деплоя эти страницы раздаются как обычные статические файлы через CDN.
Как это работает
Сборка (next build)
Next.js вызывает серверный компонент или getStaticProps, выполняет все запросы к API/БД и генерирует HTML-файлы для каждой страницы.
Деплой
Готовые HTML-файлы размещаются на CDN. Сервер больше не участвует в генерации страниц.
Запрос пользователя
Когда пользователь открывает страницу, CDN мгновенно отдает готовый HTML. Никакого ожидания сервера, никакого рендеринга в реальном времени.
SSG в App Router
В App Router (Next.js 13+) SSG является поведением по умолчанию. Если компонент не использует динамические данные, Next.js автоматически сгенерирует его статически:
// app/docs/page.tsx
// Эта страница будет сгенерирована статически при сборке
export default async function DocsPage() {
const res = await fetch('https://api.hackfrontend.com/docs')
const docs = await res.json()
return (
<ul>
{docs.map((doc: { slug: string; title: string }) => (
<li key={doc.slug}>{doc.title}</li>
))}
</ul>
)
}
По умолчанию fetch в серверных компонентах кеширует результат. Это эквивалент SSG: запрос выполняется один раз при сборке.
Динамические роуты
Для динамических страниц нужно заранее указать, какие пути генерировать. Для этого используется generateStaticParams:
// app/docs/[slug]/page.tsx
export async function generateStaticParams() {
const res = await fetch('https://api.hackfrontend.com/docs')
const docs = await res.json()
return docs.map((doc: { slug: string }) => ({
slug: doc.slug
}))
}
export default async function DocPage({
params
}: {
params: { slug: string }
}) {
const res = await fetch(
`https://api.hackfrontend.com/docs/${params.slug}`
)
const doc = await res.json()
return (
<article>
<h1>{doc.title}</h1>
<div>{doc.content}</div>
</article>
)
}
При сборке Next.js вызовет generateStaticParams, получит список slug'ов и сгенерирует отдельный HTML для каждого.
SSG в Pages Router (Legacy)
В Pages Router для SSG используется getStaticProps:
// pages/docs/index.tsx
export async function getStaticProps() {
const res = await fetch('https://api.hackfrontend.com/docs')
const docs = await res.json()
return {
props: { docs }
}
}
export default function DocsPage({ docs }) {
return (
<ul>
{docs.map(doc => (
<li key={doc.slug}>{doc.title}</li>
))}
</ul>
)
}
Для динамических роутов дополнительно используется getStaticPaths:
// pages/docs/[slug].tsx
export async function getStaticPaths() {
const res = await fetch('https://api.hackfrontend.com/docs')
const docs = await res.json()
return {
paths: docs.map(doc => ({ params: { slug: doc.slug } })),
fallback: false
}
}
export async function getStaticProps({ params }) {
const res = await fetch(
`https://api.hackfrontend.com/docs/${params.slug}`
)
const doc = await res.json()
return { props: { doc } }
}
Когда использовать SSG
Подходит:
- Документация (как на Hack Frontend)
- Блоги и статьи
- Лендинги, маркетинговые страницы
- FAQ, справочные разделы
- Каталог товаров, который обновляется редко
Не подходит:
- Страницы с персонализированным контентом (профиль, дашборд)
- Данные, которые меняются каждую секунду (котировки, чаты)
- Страницы, зависящие от cookies или заголовков запроса
На собеседовании:
Частый вопрос: "А что если данные устарели после сборки?". Ответ: для этого существует ISR (Incremental Static Regeneration), который позволяет обновлять статические страницы без полной пересборки.
Преимущества SSG
- Скорость. Готовый HTML отдается мгновенно. Нет ожидания сервера.
- SEO. Поисковые боты получают полный HTML-контент сразу.
- Надежность. Статические файлы не зависят от доступности базы данных или API в момент запроса.
- Стоимость. CDN-хостинг дешевле, чем серверный рендеринг при каждом запросе.
Полезные ресурсы
- nextjs.org/docs — документация по статическому рендерингу
- generateStaticParams — API Reference