最近是在使用Next.js搭建个人blog,遇到了这个问题。原本以为使用remark插件就能轻松的把md格式转换为html格式,并且代码块自动高亮显示呢。
然并没有。简单记录下最后的解决方式。
md转html
在lib的工具函数中,我引入了remark和html
import { remark } from "remark";
import html from "remark-html";
...
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(html)
.use(codeblocks)
.process(matterResult.content);
const contentHtml = processedContent.toString();
所以在文章详情的页面中,直接使用contentHtml。
export default function Post({ postData }) {
return (
<Layout>
<Head>
<title>{postData.title}</title>
</Head>
<div className="w-full mx-0 mt-6 overflow-scroll">
{postData.title}
<br />
{postData.id}
<br />
<Date dateString={postData.date} />
<br />
<div
dangerouslySetInnerHTML={{ __html: postData.contentHtml }}
/>
</div>
</Layout>
);
}
最后出来页面上出来的效果是这样的。。
看上去简直像毛坯房!藍
应该是少了code block样式之类的东西,去remark的插件列表找了一下。尝试了几个插件后,都没有效果。
一波google下来找到了**highlight.js**插件。用起来还挺简单。果断一波先一波import!
使用highlight.js
还是在上面的文章详情的页面中
import "highlight.js/styles/github.css"; // github样式文件
import hljs from "highlight.js/lib/core"; // highlight.js核心
import javascript from "highlight.js/lib/languages/javascript"; // 单独使用js部分
hljs.registerLanguage("jsx", javascript);
hljs.highlightAll();
command+s !!
廊廊廊
解决报错
这里报错了,应该是hljs是直接作用在dom上而这个时候组件并没有渲染到页面上。顺着这个思路,想到加一个useEffect就好了。然后把hljs的调用放在useEffect中执行。最终效果如下。
这样就解决了markdown转html后,代码块没有样式的问题。
最后附上这个页面的完整代码。
import Layout from "../../components/layout";
import { getAllPostIds, getPostData } from "../../lib/posts";
import Head from "next/head";
import Date from "../../components/date";
import "highlight.js/styles/github.css";
import hljs from "highlight.js/lib/core";
import javascript from "highlight.js/lib/languages/javascript";
import { useEffect } from "react";
export default function Post({ postData }) {
useEffect(() => {
hljs.registerLanguage("jsx", javascript);
hljs.highlightAll();
});
return (
<Layout>
<Head>
<title>{postData.title}</title>
</Head>
<div className="w-full mx-0 mt-6 overflow-scroll">
{postData.title}
<br />
{postData.id}
<br />
<Date dateString={postData.date} />
<br />
<div
dangerouslySetInnerHTML={{ __html: postData.contentHtml }}
/>
</div>
</Layout>
);
}
export async function getStaticPaths() {
// Return a list of possible value for id
const paths = getAllPostIds();
console.log("getStaticPaths", paths);
return {
paths,
fallback: false,
};
}
export async function getStaticProps({ params }) {
// Fetch necessary data for the blog post using params.id
const postData = await getPostData(params.id);
return {
props: {
postData,
},
};
}