Next.js 製 Markdown ブログでシンタックスハイライトを実現する
はじめに
このブログは remark, remark-html を利用して Markdown をレンダリングしている。
remark-prism を利用したシンタックスハイライトの導入に少し手間取ったので、手順をまとめる。
手順
remark-prism をインストールする。
> npm install remark-prism
lib/markldownToHtml.ts
に remark-prism
を導入する。
import { remark } from 'remark'
import html from 'remark-html'
import prism from 'remark-prism' // syntax highlighter として remark-prism を利用する。
export default async function markdownToHtml(markdown: string, slug?: string) {
const markdownReplacedImgPath = markdown.replace(//assets/images/posts/nextjs-markdown-syntax-highlight/g, `/assets/images/posts/${slug}`)
const result = await remark()
.use(html, { sanitize: false }) // sanitize: false を指定しないとシンタックスハイライトが有効にならない。
.use(prism)
.process(markdownReplacedImgPath)
return result.toString()
}
以上👍
Sanitize とは
wiki を見る限り、エスケープのことだった。
In data sanitization, HTML sanitization is the process of examining an HTML document and producing a new HTML document that preserves only whatever tags are designated "safe" and desired.
HTML sanitization can be used to protect against attacks such as cross-site scripting (XSS) by sanitizing any HTML code submitted by a user.
{ sanitize: false } って、大丈夫なの??
false にすると、Sanitize されていない HTML が出力される。
How to sanitize the output (Object or boolean, default: true):
false — output is not sanitized, dangerous raw HTML persists true — output is sanitized according to GitHub’s sanitation rules, dangerous raw HTML is dropped Object — schema that defines how to sanitize output with hast-util-sanitize, dangerous raw HTML is dropped
XSS のリスクが無ければ、sanitize: false
で問題ない。
アプリケーション内部の Markdown ファイルをレンダリングする処理には XSS のリスクはないため、このブログに関しては sanitize: false
で問題ない。
おわりに
{ sanitize: false }
の設定が必要なことが分からず、手間取ってしまった。
{ sanitize: true }
にした場合、シンタックスハイライトが有効にならない理由は分かっていない。シンタックスハイライトに必要な文字が Sanitize によって失われる(他の文字に置換される)ことが原因だろう。もう少し、深掘りたい気持ちがあるが、他に考えたいテーマがあるので、この件は一旦ここまでとする。