1. getStaticPath 예시
2. fallback
동적 라우팅 페이지에서의 pre-rendering
Next의 pages폴더에서 [대괄호]로 파일명을 생성하면 동적 라우팅을 할 수 있다.
이 때 주의해야 할 점은 Next는 모든 페이지를 사전생성 하지만, 동적 페이지에서는 그렇지 않다는 점이다.
동적 페이지에서 getStaticProps를 사용하여서 페이지에 진입하게 되면 아래와 같은 에러를 만나게 된다.
대괄호 [ ]로 만든 동적 페이지는 엄밀하게 따져서 하나의 페이지가 아닌 여러 페이지이다.
때문에 Next는 사전에 동적 페이지를 위해서 얼마나 많은 페이지를 미리 생성해야할지 알 수 없다.
이럴 때 비동기 함수 getStaticPaths를 이용하여 Next에게 어떤값에 대한 페이지가 pre-rendering되어야 할 지 지정해준다.
정확히 말해 동적 페이지의 어떤 구체적인 인스턴스를 사전에 생성할지 알려주는 것이다.
Multiple concrete [id] page instances (ex. id=1, id=2 etc) are pre-generated.
getStaticPath 예시
예를들어 getStaticProps에 아래의 코드대로 /p1 /p2 /3의 동적인 페이지를 만든다고 한다면,
// dummy.json
{
"products": [
{ "id": "p1", "title": "Product 1", "description": "This is product 1" },
{ "id": "p2", "title": "Product 2", "description": "This is product 2" },
{ "id": "p3", "title": "Product 3", "description": "This is product 3" }
]
}
export async function getStaticProps(context) {
const { params } = context;
const productId = params.pid;
const filePath = path.join(process.cwd(), 'data', 'dummy.json');
const jsonData = await fs.readFile(filePath);
const data = JSON.parse(jsonData);
const product = data.products.find((product) => product.id === productId);
return {
props: {
product: product,
},
};
}
const ProductdatailPage = ({ product }) => {
return (
<>
<h1>{product.title}</h1>
<p>{product.description}</p>
</>
);
};
export default ProductdatailPage;
해당 경로를 반환하는 paths 객체를 getStaticPaths로 지정해준다.
export async function getStaticPaths() {
// paths가 있는 객체를 반환
return {
paths: [
{ params: { pid: 'p1' } },
{ params: { pid: 'p2' } },
{ params: { pid: 'p3' } },
],
fallback: false,
};
}
설정 후 다시 앱을 build해보면 getStaticPaths로 지정한 p1/p2/p3 페이지가 pre-rendering 된 것을 확인할 수 있고,
.next/server/pages폴더에도 p1~p3.html 파일이 생성된 것을 확인할 수 있다.
paths의 id값을 하드 코딩한 부분을 수정
- params : 경로상의 동적 세그먼트에 대한 구체적인 값을 알 수 있다. {key : 값}
// pages/posts/[slug].js
export function getStaticProps(context) {
const { params } = context;
const { pid } = params;
console.log('🚀 ~ file: [slug].js:21 ~ getStaticProps ~ params', params);
...
}
fallback
fallback: false
- getStaticPaths에서 리턴하지 않는 페이지는 모두 404로 연결
- page의 data가 자주 추가되지 않거나, 새로 생성되는 페이지의 수가 적을 때 사용한다.
fallback: true
- 데이터에 의존하는 정적 페이지가 많아서 모든 페이지를 pre-rendering 하는것이 무리이고 불필요하다고 생각될 때,
= 일부 페이지만 pre-rendering 하고 싶을 때 true설정한다. - 지정하지 않은 나머지 페이지는 pre-rendering되지 않고 request가 서버에 도달하는 순간 생성된다.
- 빌드 시간과 사용자들의 응답 속도를 단축할 수 있다
fallback: true is useful if your app has a very large number of static pages that depend on data (such as a very large e-commerce site). If you want to pre-render all product pages, the builds would take a very long time.
* 주의해야 할 점은 pre-rendering하지 않은 나머지 path들이 로딩되는 순간(=props로 아직 아무값도 view로 넘어오지 않은 단계)을
고려해야한다. router.isFallback이 true일 때 혹은 props이 아직 넘어오지 않아서 false일 때로 조건을 준다.
export async function getStaticPaths() {
return {
paths: [{ params: { pid: 'p1' } }],
fallback: true,
};
}
import { useRouter } from 'next/router';
const ProductdatailPage = ({ product }) => {
const router = useRouter();
//isFallback 상태일 때
if (router.isFallback) {
return <p>Loading...<p>;
}
return (
<>
<h1>{product.title}</h1>
<p>{product.description}</p>
</>
);
};
export default ProductdatailPage;
const ProductdatailPage = ({ product }) => {
//props이 아직 들어오지 않음
if (!product) {
return <p>Loading...<p>;
}
...
paths로 지정한 p1을 제외한 p2-p3의 html파일은 사라진 것을 확인할 수 있다.
fallback : 'blocking'
- 최초 만들어놓지않은 path에 대한 요청이 들어온 경우 fallback 상태를 보여주지 않고 SSR로 동작 (서버에서 완전히 pre-rendering된 후 html이 생성되면) 한다.
- SSR로 동작하기 때문에 loading/fallback 상태가 필요없다.
- 한 번 방문한 경로는 pre-rendered pages 목록에 추가되어, 최초 build타임에 pre-rendering 되어진 경로와 동일하게 동작한다.
- next export 사용 시 'blocking'은 지원되지 않는다.
* fallback : true 일 때, 사전에 정의되지 않은 경로로 진입 시 에러가 발생할 수 있으므로
지정된 경로가 아닐 시 notFound : true로 404 페이지로 이동하도록 한다.
'Archive' 카테고리의 다른 글
[알고리즘/JS] 최대값 최소값 제외한 배열 요소의 합 (reduce) (1) | 2023.01.14 |
---|---|
[Next.js] Pre-rendering 개념 & Static Generation(getStaticProps) (0) | 2023.01.08 |
[Regex] 정규 표현식 기초 (2) - 대괄호 / 부정부호 / 꺽쇠 (0) | 2022.12.05 |
[JS] JavaScript 개념 (자바스크립트 엔진, 원시형/참조형, Stack/Heap) (0) | 2022.11.28 |
[JS] JavaScript ES6 - var / let / const (0) | 2022.11.25 |