getStaticPaths
При экспорте функции getStaticPaths
из страницы, использующей Динамические маршруты, Next.js будет статически предварительно рендерить все пути, указанные в getStaticPaths
.
import type {
InferGetStaticPropsType,
GetStaticProps,
GetStaticPaths,
} from 'next'
type Repo = {
name: string
stargazers_count: number
}
export const getStaticPaths = (async () => {
return {
paths: [
{
params: {
name: 'next.js',
},
}, // См. раздел "paths" ниже
],
fallback: true, // false или "blocking"
}
}) satisfies GetStaticPaths
export const getStaticProps = (async (context) => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const repo = await res.json()
return { props: { repo } }
}) satisfies GetStaticProps<{
repo: Repo
}>
export default function Page({
repo,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return repo.stargazers_count
}
export async function getStaticPaths() {
return {
paths: [
{
params: {
name: 'next.js',
},
}, // См. раздел "paths" ниже
],
fallback: true, // false или "blocking"
}
}
export async function getStaticProps() {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const repo = await res.json()
return { props: { repo } }
}
export default function Page({ repo }) {
return repo.stargazers_count
}
Возвращаемые значения getStaticPaths
Функция getStaticPaths
должна возвращать объект со следующими обязательными свойствами:
paths
Ключ paths
определяет, какие пути будут предварительно отрендерены. Например, предположим, что у вас есть страница с Динамическими маршрутами под названием pages/posts/[id].js
. Если вы экспортируете getStaticPaths
из этой страницы и вернёте следующее для paths
:
return {
paths: [
{ params: { id: '1' }},
{
params: { id: '2' },
// при настройке i18n можно также вернуть локаль для пути
locale: "en",
},
],
fallback: ...
}
Тогда Next.js статически сгенерирует /posts/1
и /posts/2
во время next build
, используя компонент страницы в pages/posts/[id].js
.
Значения каждого объекта params
должны соответствовать параметрам, используемым в имени страницы:
- Если имя страницы
pages/posts/[postId]/[commentId]
, тоparams
должен содержатьpostId
иcommentId
. - Если страница использует catch-all маршруты типа
pages/[...slug]
, тоparams
должен содержатьslug
(который является массивом). Если этот массив['hello', 'world']
, то Next.js статически сгенерирует страницу по адресу/hello/world
. - Если страница использует опциональный catch-all маршрут, используйте
null
,[]
,undefined
илиfalse
для рендеринга корневого маршрута. Например, если вы укажетеslug: false
дляpages/[[...slug]]
, Next.js статически сгенерирует страницу/
.
Строки в params
чувствительны к регистру и желательно нормализовать их, чтобы пути генерировались корректно. Например, если для параметра возвращается WoRLD
, это будет соответствовать только пути WoRLD
, но не world
или World
.
Отдельно от объекта params
можно вернуть поле locale
при настройке i18n, которое определяет локаль для генерируемого пути.
fallback: false
Если fallback
имеет значение false
, то любые пути, не возвращённые getStaticPaths
, приведут к 404 странице.
При запуске next build
Next.js проверит, вернул ли getStaticPaths
fallback: false
, и затем соберёт только пути, возвращённые getStaticPaths
. Этот вариант полезен, если у вас небольшое количество путей для создания или новые данные страниц добавляются нечасто. Если вам нужно добавить больше путей при fallback: false
, вам потребуется снова запустить next build
, чтобы новые пути могли быть сгенерированы.
Следующий пример предварительно рендерит по одной записи блога на странице pages/posts/[id].js
. Список записей будет получен из CMS и возвращён getStaticPaths
. Затем для каждой страницы данные записи будут получены из CMS с помощью getStaticProps
.
function Post({ post }) {
// Рендеринг записи...
}
// Эта функция вызывается во время сборки
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 }
}
// Эта функция также вызывается во время сборки
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 } }
}
export default Post
fallback: true
Если fallback
имеет значение true
, поведение getStaticProps
изменяется следующим образом:
- Пути, возвращённые из
getStaticPaths
, будут отрендерены вHTML
во время сборки с помощьюgetStaticProps
. - Пути, не сгенерированные во время сборки, не приведут к 404 странице. Вместо этого Next.js будет показывать «fallback»-версию страницы при первом запросе такого пути. Веб-краулеры, такие как Google, не получат fallback, и путь будет вести себя как при
fallback: 'blocking'
. - При переходе на страницу с
fallback: true
черезnext/link
илиnext/router
(на стороне клиента) Next.js не будет показывать fallback, и страница будет вести себя какfallback: 'blocking'
. - В фоновом режиме Next.js статически сгенерирует запрошенный путь
HTML
иJSON
. Это включает выполнениеgetStaticProps
. - После завершения браузер получит
JSON
для сгенерированного пути. Это будет использовано для автоматического рендеринга страницы с требуемыми props. С точки зрения пользователя, страница переключится с fallback-версии на полную версию. - Одновременно Next.js добавит этот путь в список предварительно отрендеренных страниц. Последующие запросы к тому же пути будут обслуживать сгенерированную страницу, как и другие страницы, предварительно отрендеренные во время сборки.
Важно:
fallback: true
не поддерживается при использованииoutput: 'export'
.
Когда полезен fallback: true
?
fallback: true
полезен, если ваше приложение имеет очень большое количество статических страниц, зависящих от данных (например, очень крупный интернет-магазин). Если вы хотите предварительно отрендерить все страницы товаров, сборка займёт очень много времени.
Вместо этого вы можете статически сгенерировать небольшое подмножество страниц и использовать fallback: true
для остальных. Когда кто-то запросит страницу, которая ещё не сгенерирована, пользователь увидит страницу с индикатором загрузки или скелетоном компонента.
Вскоре после этого getStaticProps
завершится, и страница будет отрендерена с запрошенными данными. С этого момента все, кто запрашивает ту же страницу, будут получать статически предварительно отрендеренную страницу.
Это гарантирует, что пользователи всегда получают быстрый опыт, сохраняя при этом быструю сборку и преимущества статической генерации.
fallback: true
не обновляет сгенерированные страницы. Для этого используйте Инкрементальную статическую регенерацию.
fallback: 'blocking'
Если fallback
имеет значение 'blocking'
, новые пути, не возвращённые getStaticPaths
, будут ждать генерации HTML
, аналогично SSR (отсюда и blocking), а затем кэшироваться для будущих запросов, так что это произойдёт только один раз для каждого пути.
getStaticProps
будет вести себя следующим образом:
- Пути, возвращённые из
getStaticPaths
, будут отрендерены вHTML
во время сборки с помощьюgetStaticProps
. - Пути, не сгенерированные во время сборки, не приведут к 404 странице. Вместо этого Next.js выполнит SSR при первом запросе и вернёт сгенерированный
HTML
. - После завершения браузер получит
HTML
для сгенерированного пути. С точки зрения пользователя, переход будет от "браузер запрашивает страницу" к "полная страница загружена". Не будет мигания состояния загрузки/fallback. - Одновременно Next.js добавит этот путь в список предварительно отрендеренных страниц. Последующие запросы к тому же пути будут обслуживать сгенерированную страницу, как и другие страницы, предварительно отрендеренные во время сборки.
fallback: 'blocking'
по умолчанию не обновляет сгенерированные страницы. Для обновления сгенерированных страниц используйте Инкрементальную статическую регенерацию вместе с fallback: 'blocking'
.
Важно:
fallback: 'blocking'
не поддерживается при использованииoutput: 'export'
.
Fallback-страницы
В «fallback»-версии страницы:
- Props страницы будут пустыми.
- Используя router, вы можете определить, рендерится ли fallback:
router.isFallback
будетtrue
.
Следующий пример демонстрирует использование isFallback
:
import { useRouter } from 'next/router'
function Post({ post }) {
const router = useRouter()
// Если страница ещё не сгенерирована, будет показано это
// до завершения выполнения getStaticProps()
if (router.isFallback) {
return <div>Загрузка...</div>
}
// Рендеринг записи...
}
// Эта функция вызывается во время сборки
export async function getStaticPaths() {
return {
// Только `/posts/1` и `/posts/2` генерируются во время сборки
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
// Включаем статическую генерацию дополнительных страниц
// Например: `/posts/3`
fallback: true,
}
}
// Эта функция также вызывается во время сборки
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 },
// Регенерировать запись не чаще раза в секунду
// при поступлении запроса
revalidate: 1,
}
}
export default Post
История версий
Версия | Изменения |
---|---|
v13.4.0 | App Router теперь стабилен с упрощённым получением данных, включая generateStaticParams() |
v12.2.0 | On-Demand Инкрементальная статическая регенерация стабильна. |
v12.1.0 | Добавлена On-Demand Инкрементальная статическая регенерация (бета). |
v9.5.0 | Стабильная Инкрементальная статическая регенерация |
v9.3.0 | Введена getStaticPaths . |