getStaticProps

getStaticProps라는 함수를 내보내면, 함수에서 반환된 props를 사용하여 빌드 시점에 페이지를 사전 렌더링합니다:

pages/index.tsx
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
}
pages/index.js
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에서 사용하기위해 모듈을 최상위 스코프에서 import 할 수 있습니다. 사용된 import는 클라이언트 측 번들에 포함되지 않습니다. 이는 서버 측 코드를 getStaticProps에서 직접 작성할 수 있다는 것을 의미하며, 여기에는 데이터베이스에서 데이터를 가져오는 작업이 포함됩니다.

Context parameter

context 매개변수는 다음 키를 포함하는 객체입니다:

이름설명
params동적 경로를 사용하는 페이지의 경로 매개변수를 포함합니다. 예를 들어, 페이지 이름이 [id].js인 경우, params{ id: ... }와 같습니다. 이는 나중에 설명할 getStaticPaths와 함께 사용해야 합니다.
preview(draftMode에서는 더 이상 사용되지 않습니다.) 페이지가 미리 보기 모드일 경우 true이고, 그렇지 않을 경우 false입니다.
previewData(draftMode에서는 더 이상 사용되지 않습니다.) setPreviewData에 의해 설정된 미리 보기 데이터입니다.
draftMode페이지가 Draft Mode일 경우 true이고, 그렇지 않을 경우 false입니다.
locale활성화된 로케일을 포함합니다 (활성화된 경우).
locales지원하는 모든 로케일을 포함합니다 (활성화된 경우).
defaultLocale구성된 기본 로케일을 포함합니다 (활성화된 경우).
revalidateReason함수가 호출된 이유를 제공합니다. 다음 중 하나일 수 있습니다: "build" (빌드 시점에 실행), "stale" (재검증 기간 만료 또는 개발 모드에서 실행), "on-demand" (온디맨드 재검증을 통해 트리거됨)

getStaticProps return values

getStaticProps 함수는 선택적 revalidate 프로퍼티와 함께 props, redirect 또는 notFound가 포함된 객체를 반환해야 합니다.

props

props 객체는 키-값 쌍으로, 각 값은 페이지 컴포넌트에서 받습니다. 전달된 모든 props들이 JSON.stringify (opens in a new tab)로 직렬화될 수 있도록, 이 값은 직렬화 가능한 객체 (opens in a new tab)여야 합니다.

export async function getStaticProps(context) {
  return {
    props: { message: `Next.js is awesome` }, // 이 값은 페이지 컴포넌트에 props로 전달됩니다.
  }
}

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 boolean은 페이지가 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 }, // 프로퍼티로 페이지 컴포넌트에 전달됩니다.
  }
}

알아두면 좋은 점 : fallback: false 모드에서는 getStaticPaths에서 반환된 경로만 사전 렌더링되므로 notFound가 필요하지 않습니다.

redirect

redirect 객체는 내부 또는 외부 리소스로 리디렉션할 수 있게 해줍니다. 이는 { destination: string, permanent: boolean }의 형태와 일치해야 합니다.

드물게, 구형 HTTP 클라이언트가 올바르게 리디렉션되도록 사용자 정의 상태 코드를 할당해야 하는 경우가 있습니다. 이러한 경우 permanent 프로퍼티 대신 statusCode 프로퍼티를 사용할 수 있지만, 두 가지를 동시에 사용할 수는 없습니다. 또한 next.config.js에서 리디렉션과 유사하게 basePath: false를 설정할 수 있습니다.

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에 추가해야 합니다.

Reading files: Use process.cwd()

파일은 getStaticProps의 파일시스템에서 직접 읽혀질 수 있습니다.

이렇게 하려면 파일의 전체 경로를 가져와야 합니다.

Next.js는 코드를 별도의 디렉토리로 컴파일하기 때문에 __dirname을 사용할 수 없습니다. __dirname이 반환하는 경로는 페이지 라우터와 다를 수 있기 때문입니다.

대신 process.cwd()를 사용할 수 있으며, 이는 Next.js가 실행되는 디렉토리를 제공합니다.

import { promises as fs } from 'fs'
import path from 'path'
 
// 게시물은 빌드 시점에 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')
 
    // 일반적으로 콘텐츠를 파싱/변환할 수 있습니다.
    // 예를 들어 여기에서 마크다운을 HTML로 변환할 수 있습니다.
 
    return {
      filename,
      content: fileContents,
    }
  })
  // { props: { posts }를 반환하면, 블로그 컴포넌트는 빌드 시점에 'posts'를 prop으로 받습니다.
  return {
    props: {
      posts: await Promise.all(posts),
    },
  }
}
 
export default Blog

Version History

버전변경 사항
v13.4.0앱 라우터가 데이터 페칭 단순화된 상태로 안정화되었습니다.
v12.2.0온디맨드 ISR이 안정화되었습니다.
v12.1.0온디맨드 ISR이 추가되었습니다(베타).
v10.0.0locale, locales, defaultLocale, notFound 옵션이 추가되었습니다.
v10.0.0fallback: 'blocking' 반환 옵션이 추가 되었습니다.
v9.5.0ISR이 안정화되었습니다.
v9.3.0getStaticProps가 도입되었습니다.