본문으로 건너뛰기

getStaticProps

페이지에서 getStaticProps(정적 사이트 생성)이라는 함수를 내보내면, 넥스트는 getStaticProps에서 반환된 props를 사용하여 빌드 타임에 이 페이지를 미리 렌더링합니다.

jsx
export async function getStaticProps(context) {
return {
props: {}, // 페이지 컴포넌트에 프롭으로 전달됩니다.
};
}
jsx
export async function getStaticProps(context) {
return {
props: {}, // 페이지 컴포넌트에 프롭으로 전달됩니다.
};
}
참고

렌더링 방식에 관계없이 모든 props는 페이지 컴포넌트로 전달되고 초기 HTML의 클라이언트 측에서 볼 수 있습니다. 이것은 페이지의 올바른 수화를 위한 것입니다. 클라이언트에 있으면 안 되는 민감한 정보는 props로 전달하면 안 됩니다.

사용 시기

다음 경우에 getStaticProps을 사용해야 합니다.

  • 페이지를 렌더링하는 데 필요한 데이터가 사용자의 요청에 앞서 빌드 타임에 얻을 수 있음
  • 데이터를 헤드리스 CMS에서 가져옴
  • 페이지는 SEO를 위해 사전 렌더링되어야 하며 매우 빨라야 함. getStaticPropsHTMLJSON 파일을 생성하며, 둘 다 성능을 위해 CDN에 캐시될 수 있음
  • 데이터가 공개적으로 캐시될 수 있음(사용자 테이터가 아님). 이 조건은 미들웨어를 사용하여 경로를 다시 작성하는 특정 상황에서 우회가 가능함

실행 시기

getStaticProps는 항상 서버에서 실행되고 클라이언트에서는 실행되지 않습니다. 이 도구를 사용하여 getStaticProps 내부에 작성된 코드가 클라이언트 측 번들에서 제거되었는지 확인할 수 있습니다.

  • getStaticPropsnext build 과정에서 항상 실행됨
  • getStaticPropsfallback: true를 사용할 때 뒤에서 실행됨
  • getStaticPropsfallback: blocking를 사용할 때 첫 렌더링 전에 호출됨
  • getStaticPropsrevalidate를 사용할 때 뒤에서 실행됨
  • getStaticPropsrevalidate()을 사용할 때 뒤에서 주문형으로 실행됨

증분형 정적 재생성과 함께 사용하면, getStaticProps는 오래된 페이지의 유효성을 다시 검사하고 새 페이지가 브라우저에 제공되는 동안 뒤에서 실행됩니다.

getStaticProps는 정적 HTML을 생성하므로 들어오는 요청(질의 매개변수나 HTTP 헤더)에 접근할 수 없습니다. 페이지 요청에 접근해야 하는 경우에는 getStaticProps에 추가로 미들웨어를 사용하는 것을 고려해야 합니다.

CMS에서 데이터 가져오기

다음 예시는 CMS에서 블로그 게시물 목록을 가져오는 방법을 보여줍니다.

jsx
// posts는 빌드 타임에 getStaticProps()에 의해 채워질 것입니다.
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
);
}
// 이 함수는 서버 측에서 빌드 타임에 호출됩니다.
// 클라이언트 측에서 호출되지 않으므로 데이터베이스 질의를 여기서 직접 해도 됩니다.
export async function getStaticProps() {
// posts를 얻기 위해 외부 API 엔드포인트를 호출합니다.
// 모든 데이터 가져오기 라이브러리를 사용할 수 있습니다.
const res = await fetch('https://.../posts');
const posts = await res.json();
// { props: { posts } }을 반환함으로써, Blog 컴포넌트는
// posts를 빌드 타임에 프롭으로 받을 것입니다.
return {
props: {
posts,
},
};
}
export default Blog;
jsx
// posts는 빌드 타임에 getStaticProps()에 의해 채워질 것입니다.
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
);
}
// 이 함수는 서버 측에서 빌드 타임에 호출됩니다.
// 클라이언트 측에서 호출되지 않으므로 데이터베이스 질의를 여기서 직접 해도 됩니다.
export async function getStaticProps() {
// posts를 얻기 위해 외부 API 엔드포인트를 호출합니다.
// 모든 데이터 가져오기 라이브러리를 사용할 수 있습니다.
const res = await fetch('https://.../posts');
const posts = await res.json();
// { props: { posts } }을 반환함으로써, Blog 컴포넌트는
// posts를 빌드 타임에 프롭으로 받을 것입니다.
return {
props: {
posts,
},
};
}
export default Blog;

getStaticProps API 참고getStaticProps에서 사용할 수 있는 모든 매개변수와 프롭을 다룹니다.

서버 측 코드 직접 작성하기

getStaticProps는 서버 측에서만 실행되므로 클라이언트 측에서는 실행되지 않습니다. 브라우저용 JS 번들에도 포함되지 않으므로 브라우저로 보내지 않고 직접 데이터베이스 질의를 작성할 수 있습니다.

즉, getStaticProps에서 외부 소스에서 데이터를 가져오는 API 경로를 사용하는 대신 getStaticProps에 직접 서버 측 코드를 작성할 수 있습니다.

다음 예시에서 API 경로는 CMS에서 일부 데이터를 가져오는 데 사용됩니다. 그러면 해당 API 경로가 getStaticProps에서 직접 호출됩니다. 이 방식은 추가적인 호출이 발생하여 성능이 저하됩니다. 대신 CMS에서 데이터를 가져오는 논리를 lib/ 디렉터리에서 getStaticProps에 공유할 수 있습니다.

lib/load-posts.js
jsx
// 다음 함수는 'lib/' 디렉터리에서
// getStaticProps와 API 경로에 공유됩니다.
export async function loadPosts() {
// posts를 얻기 위해 외부 API 엔드포인트를 호출합니다.
const res = await fetch('https://.../posts/');
const data = await res.json();
return data;
}
lib/load-posts.js
jsx
// 다음 함수는 'lib/' 디렉터리에서
// getStaticProps와 API 경로에 공유됩니다.
export async function loadPosts() {
// posts를 얻기 위해 외부 API 엔드포인트를 호출합니다.
const res = await fetch('https://.../posts/');
const data = await res.json();
return data;
}
pages/blog.js
jsx
import { loadPosts } from '../lib/load-posts';
// 이 함수는 서버 측에서만 실행됩니다.
export async function getStaticProps() {
// '/api' 경로를 가져오는 대신 getStaticProps에서 직접
// 동일한 함수를 호출할 수 있습니다.
const posts = await loadPosts();
// 반환되는 프롭은 페이지 컴포넌트에 전달됩니다.
return { props: { posts } };
}
pages/blog.js
jsx
import { loadPosts } from '../lib/load-posts';
// 이 함수는 서버 측에서만 실행됩니다.
export async function getStaticProps() {
// '/api' 경로를 가져오는 대신 getStaticProps에서 직접
// 동일한 함수를 호출할 수 있습니다.
const posts = await loadPosts();
// 반환되는 프롭은 페이지 컴포넌트에 전달됩니다.
return { props: { posts } };
}

또는 데이터를 가져오기를 위해 API 경로를 사용하는 대신, fetch() API를 getStaticProps에서 직접 사용하는 것도 가능합니다.

넥스트가 클라이언트 측 번들에서 제거하는 것을 확인하려면 next-code-elimination 도구를 사용할 수 있습니다.

HTML과 JSON을 정적으로 생성하기

getStaticProps가 포함된 페이지가 빌드 타임에 미리 렌더링되면, 넥스트가 페이지 HTML 파일 외에 getStaticProps의 실행 결과를 담은 JSON 파일을 생성합니다.

JSON 파일은 next/link이나 next/router를 통한 클라이언트 측 라우팅에 사용됩니다. getStaticProps를 사용하여 미리 렌더링된 페이지로 이동하면 넥스트가 이 JSON 파일(빌드 타임에 미리 계산됨)을 가져와 페이지 컴포넌트의 프롭으로 사용합니다. 즉, 클라이언트 측 페이지 전환은 내보내진 JSON만 사용하고 getStaticProps 자체를 호출하지는 않습니다.

사용 위치

getStaticProps페이지에서만 내보낼 수 있습니다. 페이지가 아닌 파일, _app, _document, _error에서는 내보낼 수 없습니다.

이런 제한이 있는 이유 중 하나는 페이지가 렌더링되기 전에 리액트에 필요한 모든 데이터가 있어야 하기 때문입니다.

또한 getStaticProps는 독립된 함수로 내보내야 합니다. getStaticProps를 페이지 컴포넌트의 프로퍼티로 추가하면 작동하지 않습니다.

참고

커스텀 앱을 만든 경우에는 pageProps를 링크 문서에 설명된 대로 페이지 컴포넌트에 전달하고 있는지 확인해야 합니다. 그러지 않으면 프롭이 비어 있을 것입니다.

개발 중의 실행 방식

개발 중(next dev)에는 getStaticProps가 모든 요청마다 호출됩니다.

미리 보기 모드

미리 보기 모드를 사용하여 빌드 타임 대신 요청 타임에 정적 생성을 우회하고 페이지를 렌더링할 수 있습니다. 예를 들어 헤드리스 CMS를 사용 중이며 초안이 게시되기 전에 미리 보는 것을 원할 수 있습니다.