우선 lib/posts.js 하단에 getPostData 함수를 추가한다. 이 함수는 id를 기준으로 게시물 데이터를 반환할 것이다.
export function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data,
};
}
pages/posts/[id].js를 열고 아래와 같이 코드를 업데이트한다.
getStaticProps 함수 내부에서 getPostData를 사용해 데이터를 가져오고 postData에 할당한다.
그리고 그것을 props로 반환한다.
import { getAllPostIds, getPostData } from '../../lib/posts';
export async function getStaticProps({ params }) {
const postData = getPostData(params.id);
return {
props: {
postData,
},
};
}
Post 컴포넌트도 아래와 같이 업데이트해준다.
export default function Post({ postData }) {
return (
<Layout>
{postData.title}
<br />
{postData.id}
<br />
{postData.date}
</Layout>
);
}
아래 url에 접속하면 각 페이지의 블로그 데이터를 확인할 수 있다.
http://localhost:3000/posts/ssg-ss
http://localhost:3000/posts/pre-rendering
과정을 그림으로 정리하면 다음과 같다.
동적 라우트 세부사항
다음은 동적 라우트에 대해 알아야 할 몇 가지 필수 정보이다.
Fetch External API or Query Database
getStaticProps와 마찬가지로 getStaticPaths도 어떤 데이터 소스에서든 데이터를 페치 할 수 있다.
우리 예제에서 getStaticPaths에서 사용되는 getAllPostIds는 외부 API 엔드포인트에서 페치할 수도 있다.
export async function getAllPostIds() {
// Instead of the file system,
// fetch post data from an external API endpoint
const res = await fetch('..');
const posts = await res.json();
return posts.map((post) => {
return {
params: {
id: post.id,
},
};
});
}
Development vs. Production
개발 모드에서는 모든 요청에 대해 getStaticPaths가 실행되고, 프로덕션에서는 빌드 시점에 getStaticPaths가 실행된다.
Fallback
getStaticPaths에서fallback: false로 반환했던걸 떠올려보자. 이게 무엇을 의미할까?
fallback이 false면 getStaticPaths에서 반환되지 않은 모든 경로는 404 페이지가 된다.
fallback이 true면 getStaticProps의 동작이 변경된다:
- getStaticPaths에서 반환된 경로는 빌드 시 HTML로 렌더링 된다.
- 빌드 시점에 생성되지 않은 경로는 404 페이지가 생성되지 않는다. 대신 Next.js는 해당 경로에 대한 첫 번째 요청 시 페이지의 "fallback" 버전을 제공한다.
- 백그라운드에서 Next.js는 요청된 경로를 정적으로 생성한다. 동일한 경로에 대한 후속 요청은 빌드 시점에 프리 렌더링된 다른 페이지와 마찬가지로 생성된 페이지를 제공한다.
fallback이 blocking이면, 새 경로는 getStaticProps를 사용하여 서버 사이드에서 렌더링 되고 향후 요청을 위해 캐시 되므로 경로당 한 번만 발생한다.
Catch-all Routes
동적 라우트는 괄호 안에 점(...) 세 개를 추가하여 모든 경로를 포착하도록 확장할 수 있다.
예를 들면 pages/posts/[...id].js는 /posts/a뿐만 아니라 /posts/a/b, /posts/a/b/c 등 과 매치된다.
이렇게 할 경우 getStaticPaths에서 다음과 같이 id 키의 값으로 배열을 반환해야 한다.
return [
{
params: {
// Statically Generates /posts/a/b/c
id: ['a', 'b', 'c'],
},
},
//...
];
그리고 params.id는 getStaticProps의 배열이 된다.
export async function getStaticProps({ params }) {
// params.id will be like ['a', 'b', 'c']
}
Router
Next.js 라우터에 액세스 하려면, next/router에서 useRouter 훅을 임포트 하여 액세스 할 수 있다.
404 Pages
사용자 정의 404 페이지를 만들려면 pages/404.js를 생성한다. 이 파일은 빌드 시점에 정적으로 생성된다.
// pages/404.js
export default function Custom404() {
return <h1>404 - Page Not Found</h1>;
}
자세한 내용은 오류 페이지 문서를 참조.
'개발 > Next.js' 카테고리의 다른 글
[Docs] Post / Index 페이지 다듬기 (0) | 2023.05.12 |
---|---|
[Docs] 동적 라우트 - 마크다운 렌더링 (0) | 2023.05.11 |
[Docs] 동적 라우트 - getStaticPaths 구현 (0) | 2023.05.10 |
[Docs] 동적 라우트(Dynamic Routes) (0) | 2023.05.10 |
[Docs] 서버 사이드 렌더링 (0) | 2023.05.10 |