DogKaeBi

[Next.js] 블로그 페이지. 마크다운 불려오기

포스트의 글 내용에 대해 고민하고 Markdown을 fetch 불려오기를 만들어보기

[Next.js] 블로그 페이지. 마크다운 불려오기

서론

처음 고민했던 방식

블로그의 포스트...
즉 "글"의 데이터 형식에 대해서 고민했다.
처음에는...

문자열 데이터도 생각해봤다.
하지만 문자열은 디자인을 추가하거나
글에 이미지를 추가하기 어렵다.

html 형식의 문자열도 생각해봤다.
react의 dangerouslySetInnerHTML을 사용하면

<div dangerouslySetInnerHTML={{ __html: data }} />

같은 방식을 사용할 수 있다.
하지만 속성 이름 자체가 위험을 알리고 있다.

나만의 조건이나 컴포넌트를 만드는 것도 생각했다.
하지만 이 경우도 내용은 문자열이고
대량의 조건 체크와
문자열을 분리하는 작업이 필요할 것 같다.


결과물 조건 정리

결국은 처음으로 돌아와서
내가 원하는 조건을 정리해봤다.

  1. 글 중간에 강조 및 코드를 넣기
  2. 이미지가 필요할 수도 있음
  3. 수정이 필요할 수도 있음

생각나는 방법은 2가지
하나는 각자 포스트를 페이지 컴포넌트를 만들기.
하나는 마크다운을 사용하고 읽기.

당연하다면 당연하지만
첫 방법은 너무 효율이 없을 것 같아서
markdown을 사용하기로 했다.



Markdown 읽기

Markdown

마크다운은 경량 마크업 언어이다.
말그대로 가벼운 텍스트 문서 작업 언어이다.

html과 호환성이 좋아서
글(텍스트) 데이터로 많이 사용된다.

이미지나 디자인을 추가하고 싶을 때,
html방식으로 작성해도 된다.
(html는 코드이고 브라우저가 읽고 ui를 만드는 것처럼 마크다운도 ui 처리가 필요하다)


Markdown 매치 계획

처음부터 난관이었다.
아직 DB(Database)가 없기 때문에...

적당한 방법은
DB에 md(Markdown)파일을 저장하고
요청에 따라서 해당 md 파일을 전달하는 방식이다.

우선 임시방편으로
public폴더에 md파일을 만들어도 같은 기능은 될 수 있다.

문제는 역시
어떻게 파일을 매치할까이다.

tempBlog라는 임시 변수를..
DB의 포스트 관련 데이터로 가정해..
tempBlog의 slug와 md파일 이름을 매치하는 방식을 사용할 수 있다.

public폴더는
get방식으로 요청만하면 되기 때문에
slug에 .md을 붙여 요청하면 된다.


Markdown 임시 파일 만들기

const tempBlog = [
  { date: "2024-01-01 00:00:00", category: "coding" title: "1", desc: "설명1", slug: "test1" },
  ...
  { date: "2024-01-09 00:00:00", category: "daily" title: "9", desc: "설명9", slug: "test9" },
];

getCardList에서 사용했던 임시 데이터이다.
[데이터 컨트롤러 편]

slug와 동일한 md파일을 public폴더에 만들었다.

<!-- .\public\test1.md -->

# h1

## h2

### h3

#### h4

테스트 _테스트_ **테스트**

Markdown 불러오기

fetch(`http://localhost:3000/${props.params.slug}.md`);

몇가지 마주한 문제점이 있다.

  1. await를 사용을 위해 사용하는 곳을 async로 만들어야 한다.
  2. Next.js에서 fetch의 주소는 상대경로가 안되었다
  3. fetch로 받은 데이터를 promise로 text()처리를 해야 했다
// .\app\blog\[slug]\page.js

export default async function Post(props) {
  const slug = props.params.slug;
  const postRes = await fetch(`http://localhost:3000/${slug}.md`);
  const data = await test.text();

  return <>{data}</>;
}


결과

해당 주소(/blog/test1)으로 들어가면
data 내용이 출력되는 것을 볼 수 있다.

하지만 아직 그냥 문자열로
모든 내용이 그대로 출력된다.

다음에는
markdown을 html에 맞게 읽기와
css로 디자인을 변경하는 것을 해봐야겠다.