결론
Next.js13 버전에서 SSG를 하려면 미리 랜더링 할 경로를 리턴하는 generateStaticParams API를 사용하세요.
마주한 에러
next.js로 블로그를 만드는 중입니다.
contentlayer를 통해 mdx로 작성한 파일을 파싱하고 콘텐츠를 생성합니다.
개발 모드에서는 잘되는 랜더링이 vercel을 통한 배포 모드에서는 404 에러가 발생했습니다.
해당 경로의 페이지나 파일을 찾을 수 없다는 뜻입니다.
왜그럴까?
Next.js에서는 폴더구조 기반으로 라우팅이 됩니다.
그중 [대괄호] 폴더 내의 파일들은 dynamic routes로
정확한 segment(url 경로)를 알지 못하고 동적 데이터로 경로를 생성하려는 경우
요청 시 혹은 빌드타임에 미리 랜더링 할 때 사용할 수 있습니다.
Next.js에서 server component인 경우 기본적으로 static rendering이 됩니다.
Next.js 공식문서에서 말하고 있는 바와 같이 내용이 동적으로 바뀌지 않는
블로그 포스트나 제품 페이지 같은 경우 static rendering을 하는 것이 좋습니다.
Next.js 프로젝트 빌드시 터미널에 위와 같은 메시지를 볼 수 있습니다.
(Static)은 정적인 HTML로 랜더링 되고 초기 데이터를 가져오는 메서드를 사용하지 않습니다.
데이터 없이 컴포넌트의 조합으로 구성된 /blog 페이지는 Static으로 랜더링이 됩니다.
contentlayer로 생성된 포스트 데이터를 가져오는 페이지인 /blog/[slug]에서는 요청 시에 SSR을 하게 되어있습니다.
slug에 해당하는 post가 없을 때 next/navigation의 notFound()를 실행시키는데
요청시점에 해당 post를 찾지 못해 404 에러가 발생한 것으로 보입니다.
해결하기
앞서 살펴본 바와 같이 dynamic routes에서는 요청 시에 혹은 빌드타임에 해당 페이지가 랜더링 됩니다.
빌드 타임에 미리 랜더링 하기 위해서는 generateStaticParams API를 사용하여 미리 랜더링 할 수 있습니다.
// Return a list of `params` to populate the [slug] dynamic segment
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
// Multiple versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
export default function Page({ params }) {
const { slug } = params
// ...
}
공식문서의 예제입니다.
위와 같이 { slug: string }[] 배열 안에 미리 랜더링할 페이지의 경로를 담아 리턴합니다.
export async function generateStaticParams() {
return [...allBlogPosts].map((blogPost) => ({
slug: blogPost.slugAsParams,
}));
}
export default function Slug({ params }: ParamsProps) {
//...
}
이제 dynamic routes를 하는 /blog/[slug]에서 SSG를 할 수 있게 되었습니다.
'트러블슈팅' 카테고리의 다른 글
[Next.js 14] 데이터 업데이트 기능 트러블 슈팅기 (4) | 2024.01.29 |
---|---|
[모모] 페이지 변경시 스크롤이 고정되는 문제 (0) | 2023.09.11 |