Markdown 블로그를 만들면서 글 URL을 /posts/hello-world
처럼 예쁘게 만들고 싶었죠?
이때 꼭 알아야 할 것이 바로 Next.js의 동적 라우팅(Dynamic Routing)입니다.
이번 글에서는 [slug].tsx
파일을 이용해 URL에 따라 Markdown 글을 렌더링하는 방법을 상세히 다룰게요.
📁 1. 동적 라우팅이란?
Next.js의 pages
폴더는 파일 기반 라우팅을 사용합니다.
즉, pages/about.tsx
를 만들면 /about
경로가 자동으로 생성돼요.
하지만 블로그 글처럼 URL이 유동적인 경우엔?
/posts/hello-world
/posts/nextjs-guide
/posts/markdown-tutorial
이럴 땐 [slug].tsx
처럼 대괄호로 감싼 파일명을 사용해 동적 라우팅을 설정합니다.
pages/
└── posts/
└── [slug].tsx
이제 /posts/xxx
형식의 URL로 접근하면 [slug].tsx
가 처리하게 됩니다.
⚙️ 2. getStaticPaths로 가능한 slug 미리 정의하기
정적 사이트 생성을 위해서는 어떤 slug들이 존재하는지 미리 Next.js에게 알려줘야 합니다.
이를 위해 getStaticPaths
함수를 사용해요.
// pages/posts/[slug].tsx
export async function getStaticPaths() {
const slugs = getAllPostSlugs(); // ["hello-world", "nextjs-guide"]
const paths = slugs.map((slug) => ({
params: { slug },
}));
return {
paths,
fallback: false, // 지정되지 않은 경로는 404
};
}
getAllPostSlugs
는 posts
폴더에서 Markdown 파일명을 읽어오는 함수입니다:
export function getAllPostSlugs() {
const fileNames = fs.readdirSync(postsDirectory);
return fileNames.map((fileName) => fileName.replace(/\.md$/, ""));
}
📥 3. getStaticProps로 글 내용 불러오기
URL에 따라 알맞은 글 내용을 불러오기 위해 getStaticProps
를 사용합니다.
export async function getStaticProps({ params }: any) {
const postData = await getPostData(params.slug);
return {
props: {
postData,
},
};
}
getPostData
함수는 Markdown 파일을 읽고, HTML로 파싱해주는 역할을 합니다:
export async function getPostData(slug: string) {
const fullPath = path.join(postsDirectory, `${slug}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const matterResult = matter(fileContents);
const processedContent = await remark().use(html).process(matterResult.content);
const contentHtml = processedContent.toString();
return {
slug,
contentHtml,
...(matterResult.data as { title: string; date: string }),
};
}
🧾 4. 동적 포스트 페이지 렌더링
[slug].tsx
파일에서 실제 페이지를 구성합니다:
export default function Post({ postData }: any) {
return (
<article className="max-w-2xl mx-auto mt-10">
<h1 className="text-3xl font-bold">{postData.title}</h1>
<p className="text-sm text-gray-500 mb-4">{postData.date}</p>
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</article>
);
}
이제 /posts/hello-world
로 접속하면 해당 Markdown 포스트가 깔끔하게 렌더링됩니다!
✅ 마무리하며
[slug].tsx
를 통해 Next.js의 동적 라우팅 구조를 완벽하게 이해하고, getStaticPaths
+ getStaticProps
조합으로 정적 블로그 글 구조를 완성할 수 있었습니다.
이제 우리는 글 작성 → Markdown 저장 → 자동 정적 페이지 생성까지 완성한 셈이죠!
“정적 사이트지만, 정적인 삶은 아니다.”
'Next.js' 카테고리의 다른 글
블로그에 다크모드 적용하기 — next-themes로 UX 높이기 (2) | 2025.06.23 |
---|---|
스타일링 선택하기 — Tailwind CSS vs Styled Components (2) | 2025.06.22 |
MDX로 Markdown에 컴포넌트 삽입하기 — 코드블럭, 이미지도 자유롭게! (1) | 2025.06.21 |
정적 블로그 구조 만들기 — Markdown 기반 포스트 렌더링하기 (2) | 2025.06.19 |
📘 Next.js로 블로그 프로젝트 시작하기 — 설치부터 폴더 구조까지 (1) | 2025.06.18 |