Next.js 간단한 첫 블로그를 만들어 보자(5): 동적 라우팅(Dynamic Routes)(2)
오랜만에 이어서 글을 작성하겠습니다. 여러가지로 바빠서 작성 못했지만 이제 꾸준히 작성하여 마무리 짓겠습니다!
이전에 이어서 아래 주소를 들어가면 시작하는 곳이 똑같을 거예요
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를 지원하기에 이것을 사용하는 법을 알아보겠습니다!