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 getStaticPaths() {
  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) Данные предпросмотра, установленные с помощью setPreviewData.
draftModedraftMode имеет значение true, если страница находится в режиме черновика (Draft Mode), и false в противном случае.
localeСодержит активную локаль (если включено).
localesСодержит все поддерживаемые локали (если включено).
defaultLocaleСодержит локаль по умолчанию (если включено).

Возвращаемые значения 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, // В секундах
  }
}

Узнайте больше о инкрементальной статической регенерации (ISR).

Статус кэша страницы, использующей 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.0Роутер приложений (App 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.