getStaticPaths(Static Generation)
만약 dynamic routes를 가지고 있는 페이지가 있고, 그 페이지가 getStaticProps를 사용한다면 그 페이지는 빌드시에 HTML pre-render될때 어떤 경로의 리스트의 페이지들인지 정의할 필요가 있다.
dynamic routes를 사용하는 어떤 페이지에서 getStaticProps라 불리는 async 함수를 export한다면, Next.js는
getStaticProps에 의해 정의된 모든 paths들을 정적으로 pre-render 할 것이다.
export async function getStaticPaths() {
return {
paths: [
{ params: { ... } } // See the "paths" section below
],
fallback: true or false // See the "fallback" section below
};
}
The paths key(required)
path키는 pre-render되야하는 경로들을 정의한 것이다. pages/posts/[id].js 라는 이름의 dynamic routes를 사용하는 페이지가 있다고 가정해보자. getStaticPaths를 해당 페이지에서 export하고 paths를 다음과 같이 리턴한다.
return {
paths: [
{ params: { id: '1' } },
{ params: { id: '2' } }
],
fallback: ...
}
그럼 Next.js는 posts/1, posts/2 를 빌드시에 정적으로 생성하고, pages/posts/[id].js의 페이지 컴포넌트로서 사용된다.
- 만약 페이지 명이 pages/posts/[postId]/[commentId] 라면 params는 반드시 postId와 commentId를 포함해야한다.
- 만약 pages/[...slug] 라고 한다면 params는 반드시 slug를 배열로 포함해야한다.
The fallbackkey (required)
getStaticPaths에 의해 리턴되는 객체는 반드시 boolean속성의 fallback 키를 포함해야한다.
fallback: false
만약 fallback이 false이면 getStaticPaths에 의해 전달받지 못한 path들은 모두 404 페이지로 호출된다.
새 페이지가 자주 추가되지 않는다면 이방식은 유용하다. 만약 데이터 소스에 항목을 더 추가하고 새 페이지를 렌더링해야하는 경우엔 빌드를 다시 실행해야 한다.
아래 페이지를 예로 들어보자. getStaticPath에 의해 CMS로 부터 블로그 포스트리스트는 반환된다. 그리고 각 페이지들은 getStaticProps 에 의해 CMS로부터 각 포스트 데이터가 반환된다.
// pages/posts/[id].js
function Post({ post }) {
// Render post...
}
// This function gets called at build time
export async function getStaticPaths() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts')
const posts = await res.json()
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// We'll pre-render only these paths at build time.
// { fallback: false } means other routes should 404.
return { paths, fallback: false }
}
// This also gets called at build time
export async function getStaticProps({ params }) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
// Pass post data to the page via props
return { props: { post } }
}
export default Post
만약 fallback이 true이면 getStaticProps의 행동이 변한다.
- getStaticPaths로 부터 리턴된 경로들은 getStaticProps에 의해 빌드시에 HTML로 render된다.
- 빌드시에 생성되지 않은 경로들은 404페이지로 로드되지 않는다. 대신 첫번째요청시에 "fallback"버전을 제공한다.
fallback: true는 next next 사용시 지원되지 않는다.
Fallback Pages: 로딩페이지 같은 역할
"fallback" 버전의 페이지는
- 페이지의 props는 비워진다.
- 라우터사용시 fallback이 렌더되면 router.isFallback이 true값이 되는데 이로인해 fallback이 렌더링 되었다는 것을 확인할 수 있다.
// pages/posts/[id].js
import { useRouter } from 'next/router'
function Post({ post }) {
const router = useRouter()
// If the page is not yet generated, this will be displayed
// initially until getStaticProps() finishes running
if (router.isFallback) {
return <div>Loading...</div>
}
// Render post...
}
// This function gets called at build time
export async function getStaticPaths() {
return {
// Only `/posts/1` and `/posts/2` are generated at build time
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
// Enable statically generating additional pages
// For example: `/posts/3`
fallback: true,
}
}
// This also gets called at build time
export async function getStaticProps({ params }) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
// Pass post data to the page via props
return {
props: { post },
// Re-generate the post at most once per second
// if a request comes in
revalidate: 1,
}
}
export default Post
When is fallback : true Useful?
fallback: true 는 app이 매우 많은 양의 정적페이지를 가지고 있을때 유용하다. 어떤 사람들이 아직 생성되지 않은 페이지들을 요청할 수 있다. 그때 그 유저는 로딩창을 볼 수 있을것이다. 다만 생성된 페이지들을 업데이트 하지 않는다.
업데이트하려면 ISR을 fallback true와 같이 쓰도록 하자.
fallback : 'blocking'
만약 fallback이 blocking이라면 getStaticPath에 의해 리턴되지 않은 새로운 페이지들은 HTML이 생성될 때 까지
기다릴 것이다. 원래는 데이터 받고 HTML이 생성되지만 그 반대로 작동한다.
- getStaticPaths로 부터 반환된 경로들은 getStaticProps에 의해 빌드시 HTML로 render된다.
- 빌드시에 생성되지 않은 경로들이 404페이지로 가지 않는다.
- loading/fallback 상태가 없고 그냥 요청된 페이지가 바로 로드된다.
fallback : 'blocking'은 next export 사용시 지원되지 않는다.
When should I use getStaticPaths?
동적 라우트를 사용해서 페이지를 정적으로 pre-rendering한다면 ( pages/[id].js ) 반드시 getStaticPaths를 써야한다.
TypeScript: Use GetStaticPaths
타입스크립트에서는 next에서 GetStaticPaths를 import 할 수 있다.
import { GetStaticPaths } from 'next'
export const getStaticPaths: GetStaticPaths = async () => {
// ...
}
Technical details
- getStaticProps를 동적 라우트 파라미터와 함께 사용한다면 getStaticPaths는 무조건 써야한다. getStaticPaths는 getServerSideProps와 절대 같이 사용할 수 없다.
- getStaticPaths는 서버사이드에서 빌드시에만 실행된다.
- getStaticPaths는 page에서만 exported 될 수 있다. page가 아닌곳에선 export 할 수 없다.
- 개발환경에서는 getStaticPaths는 매 요청시에 호출된다.
'Front-End > Next.js' 카테고리의 다른 글
Next.js | 기본기능 | Built-In CSS Support (0) | 2021.10.13 |
---|---|
Next.js | 기본기능 | Data fetching(4) | getServerSideProps (0) | 2021.10.13 |
Next.js | 기본기능 | Data fetching(2) | Incremental Static Regeneration (0) | 2021.10.13 |
Next.js | 기본기능 | Data fetching(1) (0) | 2021.10.08 |
Next.js | 기본기능 | Pages (0) | 2021.10.08 |