Next.js 13 react-markdown, syntax-highlighter 사용하기

버건디·2023년 3월 30일
0

Next.js

목록 보기
35/52
post-custom-banner

- React-markdown, remark-gfm 설치

npm install react-markdown remark-gfm

- react-syntax-highlighter 설치

npm install --save react-syntax-highlighter
npm install --save @types/react-syntax-highlighter // 타입스크립트용
import PostDetailPage from "@/components/Posts/PostDetailPage";
import { getPostData } from "@/app/api/getData/getData";

type Params = {
  id: string;
};

export default async function Page({ params }: { params: Params }) {
  const pageParams = params.id;
  const postData = await getPostData(pageParams);

  return (
    <>
      <PostDetailPage postData={postData} />
    </>
  );
}
import classes from "./PostDetailPage.module.css";
import { PostData } from "../../../types/Type";
import MarkDownPost from "./MarkDownPost";
import Image from "next/image";

type postType = {
  postData: PostData;
};

export default function PostDetailPage({ postData }: postType) {
  return (
    <div>
      <Image
        src={postData.imgUrl}
        width={500}
        height={500}
        alt={postData.title}
      />
      <h1>{postData.title}페이지</h1>
      <MarkDownPost post={postData.content} />
    </div>
  );
}

- MarkDownPost (라이브러리 쓸 컴포넌트)

"use client";
import classes from "./MarkDownPost.module.css";
import ReactMarkdown from "react-markdown";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { materialDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
import remarkGfm from "remark-gfm";
import Image from "next/image";

type postType = {
  post: string;
};

export default function MarkDownPost({ post }: postType) {
  return (
    <div className={classes.markdown_container}>
      <ReactMarkdown
        remarkPlugins={[remarkGfm]} // Allows us to have embedded HTML tags in our markdown
        components={{
          code({ node, inline, className, children, ...props }) {
            const match = /language-(\w+)/.exec(className || "");
            return !inline && match ? (
              <SyntaxHighlighter
                language={match[1]}
                PreTag="div"
                {...props}
                style={materialDark}
              >
                {String(children).replace(/\n$/, "")}
              </SyntaxHighlighter>
            ) : (
              <code {...props}>{children}</code>
            );
          },
          img: (image) => (
            <Image
              src={image.src || ""}
              alt={image.alt || ""}
              width={500}
              height={300}
              className={classes.markdown_container_img}
            />
          ),
        }}
      >
        {post}
      </ReactMarkdown>
    </div>
  );
}
.markdown_container_img{
    width: 100%;
    height : auto;
    max-height: 300px;
    object-fit : contain;
}

"use client" 선언을 안해주어서 계속 에러가 떠서 애먹었는데.. 깃허브 이슈를 보니 패키지 자체의 문제인듯하다.

일단은 클라이언트 컴포넌트로 선언해서 사용해주어야한다.

또 SyntaxHighlighter 컴포넌트에서 style 이 {...props}속성에서 받아와서 지정해주는것이기 때문에 밑에 있어야한다.

또한 Image 컴포넌트를 불러와서 img 속성을 따로 정의해주어서 따로 클래스를 지정해주어서 스타일링 해주었다.

profile
https://brgndy.me/ 로 옮기는 중입니다 :)
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 6월 17일

블로그 개발한다고 사용하려던 react-syntax-highlighter 사용한다고 애먹었는데... 정말 큰 도움 되었습니다. 감사합니다!

1개의 답글