Как работает Static Site Generation (SSG) в Next.js

SSG (Static Site Generation) это стратегия рендеринга, при которой HTML-страницы генерируются один раз на этапе сборки (next build). После деплоя эти страницы раздаются как обычные статические файлы через CDN.

Как это работает

1

Сборка (next build)

Next.js вызывает серверный компонент или getStaticProps, выполняет все запросы к API/БД и генерирует HTML-файлы для каждой страницы.

2

Деплой

Готовые HTML-файлы размещаются на CDN. Сервер больше не участвует в генерации страниц.

3

Запрос пользователя

Когда пользователь открывает страницу, 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-хостинг дешевле, чем серверный рендеринг при каждом запросе.

Полезные ресурсы

Связанные темы