Next+MicroCMSのハイライトをhighlight.jsからshikiへ
2024年7月17日
Next.js + Micro CMSのシンタックスハイライトは公式にも紹介されているようにcheerio + highlight.jsのようです。
サーバーサイドでシンタックスハイライト
非常にシンプルに実装できて良かったのですが、なぜか本番環境でのビルド時に以下のエラーで失敗します。
SyntaxError: Invalid regular expression: /0[oO](([0-7]_*)+)/mu: Invalid escape
検索しても、あまり同様の記事がないため、highlight.jsを諦めてshikiでのハイライトの実装を行いました。
shikiを選んだのはどうしてもサーバーサイドで処理したかったため。
コードとしては以下のように実装して、無事本番環境でもビルドすることができました。
import { type MicroCMSQueries } from 'microcms-js-sdk'
import type { Article } from '@/types'
import { client } from './fetchClient'
import { codeToHtml } from 'shiki'
import * as he from 'he'
export const fetchArticleDetail = async (
contentId: string,
queries?: MicroCMSQueries,
) => {
const data = await client.getListDetail<Article>({
customRequestInit: {
next: {
revalidate: 60,
},
},
endpoint: 'articles',
contentId,
queries,
})
const codeBlockRegex =
/<pre><code class="language-([^"]+)">([\s\S]*?)<\/code><\/pre>/g
let match
const promises = []
while ((match = codeBlockRegex.exec(data.content)) !== null) {
const [fullMatch, lang, code] = match
const decodedCode = he.decode(code)
promises.push(
codeToHtml(decodedCode, { lang, theme: 'min-light' }).then((codeHtml) => {
data.content = data.content.replace(fullMatch, codeHtml)
}),
)
}
await Promise.all(promises)
return data
}
ちゃんとハイライトできてますよね!!