getStaticProps

Экспорт функции getStaticProps позволит предварительно отрендерить страницу во время сборки, используя пропсы, возвращаемые этой функцией:

import type { InferGetStaticPropsType, GetStaticProps } from 'next'

type Repo = {
  name: string
  stargazers_count: number
}

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 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
}

Вы можете импортировать модули в глобальной области видимости для использования в getStaticProps. Импортируемые модули не будут включены в клиентскую сборку. Это означает, что вы можете писать серверный код напрямую в getStaticProps, включая запросы данных из вашей базы данных.

Параметр context

Параметр context — это объект, содержащий следующие ключи:

НазваниеОписание
paramsСодержит параметры маршрута для страниц, использующих динамические маршруты. Например, если страница называется [id].js, то params будет выглядеть как { id: ... }. Следует использовать вместе с getStaticPaths, о чём будет рассказано позже.
preview(Устарело в пользу draftMode) preview имеет значение true, если страница находится в режиме предпросмотра (Preview Mode), и false в противном случае.
previewData(Устарело в пользу draftMode) Данные предпросмотра (preview), установленные с помощью setPreviewData.
draftModedraftMode имеет значение true, если страница находится в режиме черновика (Draft Mode), и false в противном случае.
localeСодержит активную локаль (если включено).
localesСодержит все поддерживаемые локали (если включено).
defaultLocaleСодержит настроенную локаль по умолчанию (если включено).
revalidateReasonУказывает причину вызова функции. Может принимать значения: "build" (выполняется во время сборки), "stale" (срок повторной валидации истёк или выполняется в режиме разработки), "on-demand" (запущено через по требованию ревалидацию (on-demand revalidation))

Возвращаемые значения getStaticProps

Функция getStaticProps должна возвращать объект, содержащий либо props, redirect, либо notFound, а также опциональное свойство revalidate.

props

Объект props представляет собой пару ключ-значение, где каждое значение передаётся в компонент страницы. Это должен быть сериализуемый объект, чтобы любые пропсы могли быть сериализованы с помощью JSON.stringify.

export async function getStaticProps(context) {
  return {
    props: { message: `Next.js — это круто` }, // будет передано в компонент страницы как пропсы
  }
}

revalidate

Свойство revalidate определяет интервал в секундах, через который может произойти повторная генерация страницы (по умолчанию false, без повторной валидации).

// Эта функция вызывается на сервере во время сборки.
// Может быть вызвана снова на серверной функции, если
// включена ревалидация и поступает новый запрос
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    // Next.js попытается повторно сгенерировать страницу:
    // - При поступлении запроса
    // - Не чаще чем раз в 10 секунд
    revalidate: 10, // В секундах
  }
}

Подробнее о инкрементальной статической регенерации (Incremental Static Regeneration).

Статус кэша страницы, использующей ISR, можно определить по значению заголовка ответа x-nextjs-cache. Возможные значения:

  • MISS — путь отсутствует в кэше (происходит максимум один раз при первом посещении)
  • STALE — путь есть в кэше, но срок ревалидации истёк, поэтому он будет обновлён в фоне
  • HIT — путь есть в кэше и срок ревалидации не истёк

notFound

Булево значение notFound позволяет странице возвращать статус 404 и страницу 404. При notFound: true страница вернёт 404, даже если ранее была успешно сгенерирована. Это полезно для случаев, когда пользовательский контент удаляется автором. Обратите внимание, что notFound следует тем же правилам revalidate, описанным здесь.

export async function getStaticProps(context) {
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  if (!data) {
    return {
      notFound: true,
    }
  }

  return {
    props: { data }, // будет передано в компонент страницы как пропсы
  }
}

Важно: notFound не требуется для режима fallback: false, так как предварительно рендерятся только пути, возвращённые из getStaticPaths.

redirect

Объект redirect позволяет перенаправлять на внутренние или внешние ресурсы. Должен соответствовать формату { destination: string, permanent: boolean }.

В редких случаях может потребоваться указать пользовательский статус-код для корректного перенаправления в старых HTTP-клиентах. В таких случаях можно использовать свойство statusCode вместо permanent, но не оба одновременно. Также можно установить basePath: false, аналогично редиректам в next.config.js.

export async function getStaticProps(context) {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!data) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
        // statusCode: 301
      },
    }
  }

  return {
    props: { data }, // будет передано в компонент страницы как пропсы
  }
}

Если редиректы известны во время сборки, их следует добавить в next.config.js.

Чтение файлов: используйте process.cwd()

Файлы можно читать напрямую из файловой системы в getStaticProps.

Для этого необходимо получить полный путь к файлу.

Поскольку Next.js компилирует ваш код в отдельную директорию, нельзя использовать __dirname, так как возвращаемый им путь будет отличаться от маршрутизатора страниц.

Вместо этого используйте process.cwd(), который возвращает директорию, в которой выполняется Next.js.

import { promises as fs } from 'fs'
import path from 'path'

// posts будут заполнены во время сборки через getStaticProps()
function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>
          <h3>{post.filename}</h3>
          <p>{post.content}</p>
        </li>
      ))}
    </ul>
  )
}

// Эта функция вызывается на сервере во время сборки.
// Не вызывается на клиенте, поэтому можно выполнять
// прямые запросы к базе данных.
export async function getStaticProps() {
  const postsDirectory = path.join(process.cwd(), 'posts')
  const filenames = await fs.readdir(postsDirectory)

  const posts = filenames.map(async (filename) => {
    const filePath = path.join(postsDirectory, filename)
    const fileContents = await fs.readFile(filePath, 'utf8')

    // Обычно здесь происходит разбор/преобразование содержимого
    // Например, можно преобразовать markdown в HTML

    return {
      filename,
      content: fileContents,
    }
  })
  // Возвращая { props: { posts } }, компонент Blog
  // получит `posts` как пропсы во время сборки
  return {
    props: {
      posts: await Promise.all(posts),
    },
  }
}

export default Blog

История версий

ВерсияИзменения
v13.4.0App Router теперь стабилен с упрощённым получением данных
v12.2.0Инкрементальная статическая регенерация по требованию (On-Demand ISR) стала стабильной.
v12.1.0Добавлена инкрементальная статическая регенерация по требованию (On-Demand ISR) (бета).
v10.0.0Добавлены параметры locale, locales, defaultLocale и notFound.
v10.0.0Добавлен вариант возврата fallback: 'blocking'.
v9.5.0Стабильная инкрементальная статическая регенерация (ISR)
v9.3.0Введена функция getStaticProps.