이제 블로그 포스트에 진짜 html으로 주입하고, global.css를 건들여서 스타일도 입혀보도록 하겠습니다.
https://runebook.dev/ko/docs/tailwindcss/functions-and-directives
/pages/blog/[slug].tsx
import { GetStaticProps, NextPage } from "next";
import { readdirSync } from "fs";
import matter from "gray-matter";
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkHtml from "remark-html";
import Layout from "@components/layout";
const Post: NextPage<{ post: string; data: any }> = ({
post,
data,
}) => {
return (
<Layout title={data?.title} seoTitle={data?.title}>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: post }}
/>
</Layout>
);
};
export default Post;
export function getStaticPaths() {
const files = readdirSync("./posts").map((file) => {
const [name, _] = file.split(".");
return { params: { slug: name } };
});
return {
paths: files,
fallback: false,
};
}
export const getStaticProps: GetStaticProps = async (ctx) => {
const { content, data } = matter.read(
`./posts/${ctx.params?.slug}.md`
);
const { value } = await unified()
.use(remarkParse)
.use(remarkHtml)
.process(content);
return {
props: {
post: value,
data,
},
};
};
React에서 바로 html코드를 주입하는 것을 막습니다. 왜냐하면 그 안에다 악성 스크립트 코드를 집어넣으면 사용자의 정보가 탈취당할 수도 있고, 어쨋든 위험한 상황이 나올 수 있기 때문입니다.
그래서 dangerouslySetInnerHTML을 사용하기 위해서는 신뢰된 사용자나, 관리자만이 만든 글만이 등록되게 해아합니다.
그리고 스타일을 입혀야 합니다.
/styles/global.css
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
-ms-overflow-style: none;
}
::-webkit-scrollbar {
display: none;
}
@layer components {
.blog-post-content h1 {
@apply text-red-500 mb-5;
}
.blog-post-content p {
@apply mb-2 text-gray-500;
}
.blog-post-content ul {
@apply pl-10 list-disc;
}
}
다음과 같이 작성했는데, @layer compnents는 Tailwind컴포넌트의 클래스와 컴포넌트에 등록된 * 모든 컴포넌트 클래스를 주입합니다.
그리고 .blog-post-content의 자식만 적용되도록 하고 @apply를 통해서 tailwind를 inline으로 주었습니다. 이렇게 안하면 모든 페이지의 컴포넌트에 대해서 h1, p, ul태그에 적용되기 때문에 무조건 이런 형식으로 작성해 주는 것이 좋습니다.
그리고 이전에 추가하지 않은 Layout을 추가해서 md파일의 data의 title을 layout의 title, seoTitle에 주입해 주었습니다.
정상 작동합니다. 이렇게 하는 것보다 Prisma를 통해 쉽게 할 수 있었지만, 이렇게 함으로써 다양한 소스파일로부터 SSG를 구현할 수 있다는 사실을 알았습니다. 그리고 매우 편리하게 posts/에 md파일을 추가하는 것만으로 바로 SSG파일이 빌드타임에 생성된 다는 매우 편리한 이점을 가집니다. 매우 놀랍습니다.
'Web > NextJs' 카테고리의 다른 글
[ Next.js - DeepDive ] - Incremental site regeneration - 2 ( On-Demand ) (0) | 2022.08.12 |
---|---|
[ Next.js - DeepDive ] - Incremental site regeneration - 1 (0) | 2022.08.08 |
[ Next.js - DeepDive ] - Dynamic getStaticProps (0) | 2022.08.06 |
[ Next.js - DeepDive ] - getStaticProps part Two (0) | 2022.08.06 |
[ Next.js - DeepDive ] - getStaticProps part One (0) | 2022.08.06 |