chibaqn /
Posts
2022-08-04 22:17:05

Next.js 製 Markdown ブログでシンタックスハイライトを実現する

はじめに

このブログは remark, remark-html を利用して Markdown をレンダリングしている。

remark-prism を利用したシンタックスハイライトの導入に少し手間取ったので、手順をまとめる。

手順

remark-prism をインストールする。

> npm install remark-prism

lib/markldownToHtml.tsremark-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.

HTML sanitization

{ 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

https://github.com/remarkjs/remark-html

XSS のリスクが無ければ、sanitize: false で問題ない。

アプリケーション内部の Markdown ファイルをレンダリングする処理には XSS のリスクはないため、このブログに関しては sanitize: false で問題ない。

おわりに

{ sanitize: false } の設定が必要なことが分からず、手間取ってしまった。

{ sanitize: true } にした場合、シンタックスハイライトが有効にならない理由は分かっていない。シンタックスハイライトに必要な文字が Sanitize によって失われる(他の文字に置換される)ことが原因だろう。もう少し、深掘りたい気持ちがあるが、他に考えたいテーマがあるので、この件は一旦ここまでとする。