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.

pages/posts/[id].js
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:

pages/posts/[id].js
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.0App Router теперь стабилен с упрощённым получением данных, включая generateStaticParams()
v12.2.0On-Demand Инкрементальная статическая регенерация стабильна.
v12.1.0Добавлена On-Demand Инкрементальная статическая регенерация (бета).
v9.5.0Стабильная Инкрементальная статическая регенерация
v9.3.0Введена getStaticPaths.