目指せブログサービスと同等の書き心地

このブログはローカルでmarkdownを書き、GitHubにpushすることでCloudflare Workersにデプロイされる仕組みになっているのだが、そうなると問題になってくるのが画像の扱いだった。

画像を貼る動線が無い

世の中の様々なブログサービスは、基本的な機能として簡単に画像をアップロードし、それを記事内に貼り付ける仕組みが整っているが、ローカルではそうもいかない。

例えばスマートフォンで撮影した写真を例に考えてみよう。「記事内に画像を表示すること」だけを達成するなら以下のようなフローになる。

  1. スマートフォンから何らかの手段でPCに写真を持ってくる
  2. リポジトリ内に写真を配置
  3. Markdownに![](URL)で貼り付ける

流石に、記事を1つ書くのに手間が多すぎる。写真ファイルが溜まり、リポジトリ全体のサイズが肥大化するのもよろしくない。

そんなわけで、画像の扱いについてはずっと頭を悩ませてきた。

r2-image-worker

サイトをCloudflareで運用しているのもあり、料金面でも画像配信元はR2にしようと決めていたが、どうすれば面倒じゃない形でアップロードし、その画像をローカルのmarkdownに貼り付けられるかが課題だった。

ある日、yusukebeさんの「Cloudflare画像配信パターン」という記事を読み、この中で実装例として紹介されているr2-image-workerがアップロードの課題解決に効きそうだと感じた。

Cloudflare画像配信パターン

zenn.dev faviconzenn.dev
Cloudflare画像配信パターン

GitHub - yusukebe/r2-image-worker: Store and Deliver images with R2 backend Cloudflare Workers.

Store and Deliver images with R2 backend Cloudflare Workers. - yusukebe/r2-image-worker

github.com favicongithub.com
GitHub - yusukebe/r2-image-worker: Store and Deliver images with R2 backend Cloudflare Workers.

これを利用して、手元のiPhoneからはショートカット経由でr2-image-workerでアップロード。

Macでは通常の範囲選択スクリーンショットに近い 4 でショートカットを起動。範囲選択したスクリーンショットをそのままR2へアップロードし、記事用のMDC形式でクリップボードにコピーする、という挙動を実現できた。

r2-image-picker

R2に画像をアップロードする仕組みは整ったので、次はそれを簡単に編集中のmarkdown内に差し込める機能が必要になる。

これに関しては、前回のブログでも言及したが、R2の画像をターミナルから参照してMDC形式でクリップボードにコピーするというTUIツールを作成した。

Claude Codeに全て実装してもらい、自分がやったのは動作確認とフィードバックくらいだが、個人が使う分には十分な動作をしてくれている。

ちなみにこのr2-image-pickerはこのブログ専用のツールとして作っているので、独立したリポジトリではなくこのサイトのリポジトリ内のツールの1つ、という形に含めている。

ryuhei373.dev/tools/r2-image-picker at main · ryuhei373/ryuhei373.dev

ryuhei373's website. Contribute to ryuhei373/ryuhei373.dev development by creating an account on GitHub.

github.com favicongithub.com
ryuhei373.dev/tools/r2-image-picker at main · ryuhei373/ryuhei373.dev

フォーマット

最終的にMarkdownに貼り付ける文字列は以下のようになっている。

:r2-image{object-key="(アップロードした際に画像に割り当てられるUUID).png" width="xxx" height="yyy"}

標準のMarkdownのリンク形式ではなく、r2-imageというカスタムのMDCコンポーネントを用意して、オブジェクトキー、width、heightを渡す形になっている。

これにはいくつか理由があるが、レイアウトシフト抑制のためにwidthとheightをimgタグに渡すためというのが一番の大きな理由。

![](URL)の形式ではwidthとheightを渡すことができず、それだけならimgタグでも対応はできるのだけど、直接MarkdownにHTMLタグを書きたくない人種なのでこのような対応になっている。

実際に使ってみて

相当に便利で、特にMacでのスクリーンショットを利用した場合、スクリーンショットを撮ったらクリップボードに入った内容をペーストするだけで即画像が利用できる、というUXが我ながらよくできたと思っている。

最後に

ローカルでブログを書いている個人サイト勢の参考に少しでもなれば嬉しい。

次はこのサイト全体の技術スタックやらブログの更新フローみたいなところをまとめようかなと思っている。