Programming/nextjs

Next.js 간단한 첫 블로그를 만들어 보자(5): 동적 라우팅(Dynamic Routes)(2)

조용장 2022. 6. 4. 19:31

오랜만에 이어서 글을 작성하겠습니다. 여러가지로 바빠서 작성 못했지만 이제 꾸준히 작성하여 마무리 짓겠습니다!

이전에 이어서 아래 주소를 들어가면 시작하는 곳이 똑같을 거예요

https://nextjs.org/learn/basics/dynamic-routes/render-markdown

 

Learn | Next.js

Production grade React applications that scale. The world’s leading companies use Next.js by Vercel to build pre-rendered applications, static websites, and more.

nextjs.org

nextjs의 첫 앱을 만드는 방법이며 영어로 된 문서를 한글로 작성해보며 작성하고 있습니다. 틀린 부분도 있겠지만.. 지적해주시면 수정해 놓겠습니다~

 

Render Markdown

마크다운을 렌더링 하기 위해서 remark 라이브러리를 사용해야합니다. 그전에 설치를 진행해 봅시다.

npm install remark remark-html

 

그 다음 lib/posts.js를 열고 파일 맨 위에 다음과 같이 추가합니다.

import { remark } from 'remark';
import html from 'remark-html';

 

import 에 추가한 "remark"를 사용하려면 다음과 같이 동일한 파일에서 getPostData() 함수를 업데이트해야합니다.

export async 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);

  // Use remark to convert markdown into HTML string
  const processedContent = await remark()
    .use(html)
    .process(matterResult.content);
  const contentHtml = processedContent.toString();

  // Combine the data with the id and contentHtml
  return {
    id,
    contentHtml,
    ...matterResult.data,
  };
}

 

 

즉, getPostData를 호출할 때 await를 사용하려면 page/posts/[id].js의 getStaticProps를 업데이트해야 합니다

export async function getStaticProps({ params }) {
  // Add the "await" keyword like this:
  const postData = await getPostData(params.id);
  // ...
}

 

마지막으로 페이지/posts/[id].js의 Post 구성 요소를 업데이트하여 risklySetInnerHTML을 사용하여 contentHtml을 렌더링합니다.

export default function Post({ postData }) {
  return (
    <Layout>
      {postData.title}
      <br />
      {postData.id}
      <br />
      {postData.date}
      <br />
      <div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
    </Layout>
  );
}

이렇게 세팅이 된 상태로 블로그에 들어가보면 다음과 같이 컨텐츠들이 보일겁니다.

Polishing the Post Page (포스트 페이지 다듬기)

게시물 페이지에 제목 추가

pages/posts/[id].js에 post 데이터를 이용하여 title 태그를 추가해보자

먼저 파일 맨 위에 next/head를 추가하고 Post 구성 요소를 업데이트하여 title 태그를 추가합니다.

// Add this import
import Head from 'next/head';

export default function Post({ postData }) {
  return (
    <Layout>
      {/* Add this <Head> tag */}
      <Head>
        <title>{postData.title}</title>
      </Head>

      {/* Keep the existing code here */}
    </Layout>
  );
}

 

Formatting the Date

날짜 형식을 지정하기 위해 date-fns 라이브러리를 사용해 봅시다. 다음과 같이 코드를 입력하여 설치합니다.

npm install date-fns

 

다음으로 components/date.js라는 파일을 만들고 Date 구성 요소를 추가합니다.

import { parseISO, format } from 'date-fns';

export default function Date({ dateString }) {
  const date = parseISO(dateString);
  return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>;
}

 

이제 pages/posts/[id].js 를 열고 파일 맨 위에 Date component에 대한 import를 추가하고 {postData.date}를 사용합니다.

// Add this import
import Date from '../../components/date';

export default function Post({ postData }) {
  return (
    <Layout>
      {/* Keep the existing code here */}

      {/* Replace {postData.date} with this */}
      <Date dateString={postData.date} />

      {/* Keep the existing code here */}
    </Layout>
  );
}

http://localhost:3000/posts/pre-rendering 에 접속하면 "2020년 1월 1일"이라고 쓰여진 날짜를 볼 수 있습니다.

 

CSS 추가하기

끝으로 styles/utils.module.css 파일을 사용하여 CSS를 추가해 봅시다. page/posts/[id].js 파일을 열고 CSS 파일에 대한 import를 추가합니다. 또한 Post component를 다음과 같은 코드로 변경합니다.

// Add this import at the top of the file
import utilStyles from '../../styles/utils.module.css';

export default function Post({ postData }) {
  return (
    <Layout>
      <Head>
        <title>{postData.title}</title>
      </Head>
      <article>
        <h1 className={utilStyles.headingXl}>{postData.title}</h1>
        <div className={utilStyles.lightText}>
          <Date dateString={postData.date} />
        </div>
        <div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
      </article>
    </Layout>
  );
}

http://localhost:3000/posts/pre-rendering 에 액세스하면 페이지가 이제 조금 더 좋아 보일 것입니다.

이제 인덱스 페이지를 다듬어 봅시다!

인덱스 페이지 다듬기

다음으로 인덱스 페이지(pages/index.js)를 업데이트하겠습니다. Link 컴포넌트를 사용하여 각 게시물 페이지에 링크를 추가해야 합니다. pages/index.js를 열고 Link 와 Date 에 대한 파일 맨 위에 추가합니다.

import Link from 'next/link';
import Date from '../components/date';

그런 다음 동일한 파일의 Home 구성 요소 하단 근처에서 li 태그를 다음으로 교체합니다.

<li className={utilStyles.listItem} key={id}>
  <Link href={`/posts/${id}`}>
    <a>{title}</a>
  </Link>
  <br />
  <small className={utilStyles.lightText}>
    <Date dateString={date} />
  </small>
</li>

http://localhost:3000 으로 이동하면 페이지에 각 기사에 대한 링크가 있습니다.

이렇게 했다면 동적경로 관련해서는 마무리가 되었습니다.

이후에는 추가적인 팁들이 있지만 이부분은 각자 들어가서 확인해보는 것이 좋을 것 같습니다!!

https://nextjs.org/learn/basics/dynamic-routes/dynamic-routes-details

 

Learn | Next.js

Production grade React applications that scale. The world’s leading companies use Next.js by Vercel to build pre-rendered applications, static websites, and more.

nextjs.org

 

이제 Next.js에서 api routes를 지원하기에 이것을 사용하는 법을 알아보겠습니다!