WDF.
最新トレンド

Astro外でも使える、Markdown描画をユーティリティ化する設計の考え方

CSS-Tricksが、Astroで使うMarkdownコンポーネントの解説記事に続き、「どのフレームワークでも使えるMarkdownユーティリティ」というテーマの記事を公開しました。記事はReact・Vue・Svelteでも使える形を想定しており、ページ全体ではなくページの一部だけをMarkdownで扱いたいという要件は制作現場でも珍しくありません。ここでは記事のテーマである「コンポーネントからユーティリティへの切り出し」という考え方を、Webディレクターの視点で整理します。

なぜMarkdownを部品として扱いたいのか

静的サイトジェネレーターでは、1ページ=1つのMarkdownファイルという構成が一般的です。しかし実務では、ページ全体ではなく特定のブロックだけをMarkdownで管理したい場面が出てきます。

  • CMSやスプレッドシートから受け取る本文・注記
  • 利用規約やFAQなど、テキスト量が多く更新も入る領域
  • 多言語サイトで言語ごとに差し替える文言

こうしたテキストを毎回HTMLに手作業で変換して貼り付ける運用は、更新のたびにコストが発生し、担当者が変わると崩れやすくなります。文字列をそのままMarkdownとして描画できる部品があれば、原稿と実装の境界をきれいに分けられます。

原稿がページに反映されるまでの流れ
Markdownを部品として扱う場合の基本的な処理段階

Astroにおける前提

Astroにはかつて<Markdown>コンポーネントが同梱されていましたが、バージョン1で別プラグインに切り出され、バージョン3で完全に削除されたと元記事は説明しています。そのため、コンポーネントの中に渡ってきた任意の文字列をMarkdownとして描画したい場合は、別途その仕組みを用意する必要があります。CSS-Tricksの前回記事はその「なぜ・どうやって」を扱ったもので、今回の記事はそれをAstro以外にも広げる内容です。

フレームワーク非依存にする、という発想

Astroでは1つのサイト内にReactやVue、Svelteなど複数のUIフレームワークのコンポーネントを混在させられるとされています。ここでMarkdown描画をフレームワーク固有のコンポーネントとして作り込むと、フレームワークが増えるたびに同じものを作り直すことになりかねません。

解決の方向はシンプルで、「Markdown文字列を受け取ってHTMLを返す」処理をJavaScriptのユーティリティ関数として切り出し、各フレームワーク側は薄いラッパーだけを用意する形です。元記事でも、Astroではmarkdown()の戻り値を<Fragment set:html>に渡し、Svelteでは{@html}で出力するという、いずれも数行のラッパーで済む例が示されています。ロジックが1箇所に集まるため、記法の扱いや出力方針の変更も一度の修正で済むことが期待できます。

graph LR MD[Markdown文字列] --> U[共通ユーティリティ] U --> A[Astroコンポーネント] U --> R[Reactコンポーネント] U --> V[Vueコンポーネント] U --> S[Svelteコンポーネント]

ユーティリティを中心に置いた構成

実装方針を決めるときの論点

ユーティリティ化そのものは難しくありませんが、方針決めの段階で確認しておきたい点がいくつかあります。

インデントの扱い:元記事が最初に挙げている実務上の落とし穴がこれです。多くのMarkdownライブラリはコード上のインデントを考慮しないため、4スペースを超える字下げがコードブロックと解釈され、<pre><code>で囲まれた出力になってしまいます。それを避けるためにインデントを剥がして書くと、今度はコードが読みにくくなります。元記事のユーティリティはこのインデント問題を吸収し、字下げの有無にかかわらず正しいHTMLを生成するとされています。

インライン出力の有無:元記事のユーティリティにはinlineオプションがあり、trueにすると段落タグを付けずに出力します。見出しの中にMarkdownを埋め込むようなケースで使う想定です。

変換のタイミング:ビルド時に変換してHTMLを埋め込むのか、ブラウザ側で変換するのか。後者はパーサーをクライアントに配信することになるため、バンドルサイズに影響する可能性があります。原稿が更新のたびにビルドし直せる性質なら、ビルド時変換のほうが軽量になると考えられます。

サニタイズ:Markdownを描画する仕組みは最終的にHTMLを直接出力する形になります(元記事の例でもset:html{@html}が使われています)。CMSや外部入力を経由するテキストを扱うなら、XSS対策をどこで担保するかを最初に決めておきたいところです。

記法の範囲とスタイルの当て方:どこまでの記法を編集者に許容するかで、渡すガイドラインの内容が変わります。また生成されるHTMLは制作側のクラス設計から外れやすいため、ラッパー要素にまとめてスタイルを当てる方式が扱いやすくなりそうです。

フレームワークごとに実装する場合との違い
同じ処理をどこに置くかで、保守のコストが変わります

日本の制作現場での使いどころ

クライアントからの原稿がGoogleドキュメントやスプレッドシートで届く案件では、テキストの受け渡し形式をMarkdownに寄せておくと、実装への反映が定型作業になりやすくなります。特に更新頻度の高いキャンペーン文言や注記まわりは、HTMLを触らずに差し替えられる状態を作っておく価値がありそうです。

ディレクターとして押さえておきたいのは、技術選定より先に運用の線引きを決めることです。誰が原稿を更新するのか、使ってよい記法はどこまでか、更新後の反映は誰が実行するのか。この3点が曖昧なままだと、せっかく仕組みを用意しても結局実装者が毎回対応することになりかねません。

導入前に決めておきたい3点

まとめ

Markdownをページ単位ではなく部品単位で扱うと、原稿と実装の分離が進みます。その際、描画ロジックをフレームワーク固有のコンポーネントではなくユーティリティとして切り出しておけば、後からフレームワークが増えても流用しやすくなります。まずは自分の案件で「HTMLに変換して貼り付けている繰り返し作業」がどこにあるかを洗い出し、そこが対象になるかを確認するところから始めるとよさそうです。

参考リンク

Related Intelligence