Astroで外部APIから取得してきたMarkdownにコードハイライトを適用する

Aug 6, 2023

はじめに

AstroではContent collectionsなどを使ってサイトに表示するコンテンツをMarkdownで管理することができます。 しかしContentfulなどヘッドレスCMSを利用してMarkdownで記事本文を管理してる場合、コードハイライトが自動で効かないのでちょっと手を加える必要があります。 今回はその方法について紹介します。

外部APIから取得したMarkdownをHTMLに変換する

まずは外部APIから取得したMarkdownをHTMLに変換する方法ですが、ドキュメントにあるようにMarkedを使います。

以下はAstroのドキュメントにあるサンプルコードそのままです。

---
// Example: Fetch Markdown from a remote API
// and render it to HTML, at runtime.
// Using "marked" (https://github.com/markedjs/marked)
import { marked } from 'marked';
const response = await fetch('https://raw.githubusercontent.com/wiki/adam-p/markdown-here/Markdown-Cheatsheet.md');
const markdown = await response.text();
const content = marked.parse(markdown);
---
<article set:html={content} />

Shikiでコードハイライトを行う

---
import { marked } from 'marked';
import shiki from "shiki";
const response = await fetch('https://raw.githubusercontent.com/wiki/adam-p/markdown-here/Markdown-Cheatsheet.md');
const markdown = await response.text();
const highlighter = await shiki.getHighlighter({
  theme: "nord",
});

marked.use({
  renderer: {
    code(code, lang) {
      return highlighter.codeToHtml(code, { lang });
    },
  },
});
const content = marked.parse(markdown);
---
<article set:html={content} />

MarkedのRendererを使用してcodeタグ描画時にShikiのハイライト処理を挟みます。 これでハイライトが効くようになりました!

おわりに

今回はAstroでデフォルトで採用してるので合わせてShikiを使いましたが、MarkedのRendererを使えばお好みのコードハイライターライブラリでも実現可能だと思うので、ぜひ参考にしていただければと思います。