Next.js에서 getStaticPaths를 사용한 블로그 포스트 페이지 동적 생성: 마크다운 파일을 이용한 포스트 생성 방법.

작성일 :

Next.js에서 getStaticPaths를 사용한 블로그 포스트 페이지 동적 생성

Next.js는 React 기반의 웹 애플리케이션 프레임워크로, 정적 사이트 생성(SSG)과 서버 사이드 렌더링(SSR)을 지원합니다. getStaticPaths는 Next.js에서 정적 경로를 생성하기 위한 중요한 메서드입니다. 이 글에서는 마크다운 파일을 이용하여 블로그 포스트 페이지를 동적으로 생성하는 방법을 단계별로 설명합니다.

프로젝트 설정 및 마크다운 파일 준비

프로젝트를 시작하려면 먼저 Next.js 애플리케이션을 초기화해야 합니다. 아래 명령어를 통해 새로운 Next.js 프로젝트를 생성합니다:

bash
npx create-next-app my-blog
cd my-blog

프로젝트가 생성되면, 블로그 포스트를 저장할 posts 디렉토리를 만듭니다. 이 디렉토리에 마크다운 파일을 추가하여 포스트를 작성할 수 있습니다. 예를 들어 first-post.md라는 파일을 생성합니다:

posts/first-post.md:

markdown
---
title: '첫 번째 포스트'
date: '2023-10-01'
---

이것은 첫 번째 블로그 포스트입니다.

마크다운 파일을 읽기 위한 설정

마크다운 파일을 읽기 위해 gray-matterremark 패키지를 설치합니다:

bash
npm install gray-matter remark remark-html

다음으로, 마크다운 파일을 읽고 파싱하기 위한 헬퍼 파일을 만듭니다. lib/posts.js 파일을 생성합니다:

lib/posts.js:

javascript
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';

const postsDirectory = path.join(process.cwd(), 'posts');

export function getPostSlugs() {
  return fs.readdirSync(postsDirectory);
}

export function getPostBySlug(slug, fields = []) {
  const realSlug = slug.replace(/\.md$/, '');
  const fullPath = path.join(postsDirectory, `${realSlug}.md`);
  const fileContents = fs.readFileSync(fullPath, 'utf8');
  const { data, content } = matter(fileContents);

  const items = {};

  fields.forEach((field) => {
    if (field === 'slug') {
      items[field] = realSlug;
    }
    if (field === 'content') {
      items[field] = content;
    }
    if (data[field]) {
      items[field] = data[field];
    }
  });

  return items;
}

export function getAllPosts(fields = []) {
  const slugs = getPostSlugs();
  const posts = slugs.map((slug) => getPostBySlug(slug, fields));
  return posts;
}

getStaticPaths 및 getStaticProps 설정

lib/posts.js 파일이 준비되면 pages 폴더에 블로그 포스트 페이지를 생성하기 위해 [slug].js 파일을 만듭니다. 이 파일에서 getStaticPathsgetStaticProps를 설정합니다:

pages/posts/[slug].js:

javascript
import { getAllPosts, getPostBySlug } from '../../lib/posts';
import markdownToHtml from '../../lib/markdownToHtml';
import Layout from '../../components/layout';

export async function getStaticPaths() {
  const posts = getAllPosts(['slug']);

  const paths = posts.map((post) => ({
    params: {
      slug: post.slug,
    }
  }));

  return { paths, fallback: false };
}

export async function getStaticProps({ params }) {
  const post = getPostBySlug(params.slug, ['title', 'date', 'slug', 'content']);
  const content = await markdownToHtml(post.content || '');

  return {
    props: {
      post: {
        ...post,
        content,
      },
    },
  };
}

const Post = ({ post }) => {
  return (
    <Layout>
      <article>
        <h1>{post.title}</h1>
        <div>{post.date}</div>
        <div dangerouslySetInnerHTML={{ __html: post.content }} />
      </article>
    </Layout>
  );
};

export default Post;

마크다운을 HTML로 변환하기

lib 폴더에 markdownToHtml.js 파일을 생성하여 마크다운 콘텐츠를 HTML로 변환하는 함수를 추가합니다:

lib/markdownToHtml.js:

javascript
import remark from 'remark';
import html from 'remark-html';

export default async function markdownToHtml(markdown) {
  const result = await remark().use(html).process(markdown);
  return result.toString();
}

결론

이제 모든 설정이 완료되었습니다. Next.js의 getStaticPathsgetStaticProps를 사용하여 마크다운 파일을 기반으로 블로그 포스트 페이지를 동적으로 생성할 수 있습니다. 이를 통해 정적 콘텐츠와 동적 콘텐츠를 결합하여 효율적인 웹 애플리케이션을 구축할 수 있습니다. 다음 단계로는 다양한 기능을 추가하여 더 나은 사용자 경험을 제공하는 것을 고려해볼 수 있습니다.