Статическая генерация сайтов (SSG)
Примеры
- Пример с Agility CMS (Демо)
- Пример с Builder.io (Демо)
- Пример с ButterCMS (Демо)
- Пример с Contentful (Демо)
- Пример с Cosmic (Демо)
- Пример с DatoCMS (Демо)
- Пример с DotCMS (Демо)
- Пример с Drupal (Демо)
- Пример с Enterspeed (Демо)
- Пример с GraphCMS (Демо)
- Пример с Keystone (Демо)
- Пример с Kontent.ai (Демо)
- Пример с Makeswift (Демо)
- Пример с Plasmic (Демо)
- Пример с Prepr (Демо)
- Пример с Prismic (Демо)
- Пример с Sanity (Демо)
- Пример с Sitecore XM Cloud (Демо)
- Пример с Storyblok (Демо)
- Пример с Strapi (Демо)
- Пример с TakeShape (Демо)
- Пример с Tina (Демо)
- Пример с Umbraco (Демо)
- Пример с Umbraco Heartcore (Демо)
- Пример с Webiny (Демо)
- Пример с WordPress (Демо)
- Пример Blog Starter (Демо)
- Static Tweet (Демо)
Если страница использует статическую генерацию, HTML-код страницы создаётся во время сборки. Это означает, что в production HTML-код страницы генерируется при выполнении команды next build
. Этот HTML затем повторно используется при каждом запросе и может кэшироваться CDN.
В Next.js вы можете статически генерировать страницы с данными или без них. Рассмотрим оба случая.
Статическая генерация без данных
По умолчанию Next.js предварительно рендерит страницы с помощью статической генерации без получения данных. Вот пример:
function About() {
return <div>About</div>
}
export default About
Обратите внимание, что для предварительного рендеринга этой страницы не требуется получать внешние данные. В таких случаях Next.js генерирует один HTML-файл для каждой страницы во время сборки.
Статическая генерация с данными
Некоторые страницы требуют получения внешних данных для предварительного рендеринга. Есть два сценария, и один или оба могут применяться. В каждом случае вы можете использовать предоставляемые Next.js функции:
- Содержимое вашей страницы зависит от внешних данных: используйте
getStaticProps
. - Пути вашей страницы зависят от внешних данных: используйте
getStaticPaths
(обычно вместе сgetStaticProps
).
Сценарий 1: Содержимое страницы зависит от внешних данных
Пример: ваша страница блога может нуждаться в получении списка постов из CMS (системы управления контентом).
// TODO: Необходимо получить `posts` (вызовом API)
// перед предварительным рендерингом этой страницы.
export default function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
Для получения этих данных при предварительном рендеринге Next.js позволяет вам экспортировать async
функцию getStaticProps
из того же файла. Эта функция вызывается во время сборки и позволяет передать полученные данные в props
страницы при предварительном рендеринге.
export default function Blog({ posts }) {
// Рендеринг постов...
}
// Эта функция вызывается во время сборки
export async function getStaticProps() {
// Вызов API для получения постов
const res = await fetch('https://.../posts')
const posts = await res.json()
// Возвращая { props: { posts } }, компонент Blog
// получит `posts` как проп во время сборки
return {
props: {
posts,
},
}
}
Чтобы узнать больше о работе getStaticProps
, ознакомьтесь с документацией по получению данных.
Сценарий 2: Пути страниц зависят от внешних данных
Next.js позволяет создавать страницы с динамическими маршрутами. Например, вы можете создать файл pages/posts/[id].js
для отображения отдельного поста блога по id
. Это позволит вам показывать пост с id: 1
при переходе на posts/1
.
Чтобы узнать больше о динамической маршрутизации, ознакомьтесь с документацией по динамическим маршрутам.
Однако, какие id
вы хотите предварительно отрендерить во время сборки, может зависеть от внешних данных.
Пример: предположим, вы добавили в базу данных только один пост блога (с id: 1
). В этом случае вы захотите предварительно отрендерить только posts/1
во время сборки.
Позже вы можете добавить второй пост с id: 2
. Тогда вы также захотите предварительно отрендерить posts/2
.
Таким образом, пути страниц, которые предварительно рендерятся, зависят от внешних данных. Для обработки этого Next.js позволяет вам экспортировать async
функцию getStaticPaths
из динамической страницы (в данном случае pages/posts/[id].js
). Эта функция вызывается во время сборки и позволяет указать, какие пути нужно предварительно отрендерить.
// Эта функция вызывается во время сборки
export async function getStaticPaths() {
// Вызов API для получения постов
const res = await fetch('https://.../posts')
const posts = await res.json()
// Получаем пути для предварительного рендеринга на основе постов
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// Мы предварительно рендерим только эти пути во время сборки.
// { fallback: false } означает, что другие маршруты должны вернуть 404.
return { paths, fallback: false }
}
Также в pages/posts/[id].js
вам нужно экспортировать getStaticProps
, чтобы получить данные о посте с этим id
и использовать их для предварительного рендеринга страницы:
export default function Post({ post }) {
// Рендеринг поста...
}
export async function getStaticPaths() {
// ...
}
// Эта функция также вызывается во время сборки
export async function getStaticProps({ params }) {
// params содержит `id` поста.
// Если маршрут /posts/1, то params.id будет 1
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
// Передача данных поста в страницу через props
return { props: { post } }
}
Чтобы узнать больше о работе getStaticPaths
, ознакомьтесь с документацией по получению данных.
Когда следует использовать статическую генерацию?
Мы рекомендуем использовать статическую генерацию (с данными и без) везде, где это возможно, потому что ваша страница может быть собрана один раз и обслуживаться через CDN, что делает её намного быстрее, чем рендеринг на сервере при каждом запросе.
Вы можете использовать статическую генерацию для многих типов страниц, включая:
- Маркетинговые страницы
- Посты блога и портфолио
- Списки товаров в электронной коммерции
- Справка и документация
Задайте себе вопрос: "Могу ли я предварительно отрендерить эту страницу до запроса пользователя?" Если ответ "да", то следует выбрать статическую генерацию.
С другой стороны, статическая генерация не подходит, если вы не можете предварительно отрендерить страницу до запроса пользователя. Возможно, ваша страница отображает часто обновляемые данные, и её содержимое меняется при каждом запросе.
В таких случаях вы можете сделать следующее:
- Использовать статическую генерацию с получением данных на стороне клиента: вы можете пропустить предварительный рендеринг некоторых частей страницы и затем использовать JavaScript на стороне клиента для их заполнения. Чтобы узнать больше об этом подходе, ознакомьтесь с документацией по получению данных.
- Использовать рендеринг на стороне сервера (SSR): Next.js предварительно рендерит страницу при каждом запросе. Это будет медленнее, так как страница не может кэшироваться CDN, но предварительно отрендеренная страница всегда будет актуальной. Мы рассмотрим этот подход ниже.