カバー画像

Site icon image あでぃの〇〇製作所

🖼️ astro-notion-blogの画像サイズをCaptionから指定する

astro-notion-blogでは、Notion上で変更した画像のサイズが記事に適用されません。

例えばNotionではこのように表現していたとしても

astro-notion-blog上ではその情報は欠落します。

で、元の画像が大きいと

みたいな記事では

となります。

ポケモンカードの主張があまりに強くなってしまいます。アイアント、デカすぎ!

Notionにおける画像のサイズ情報はどこにあるのか

NotionはNotion自体にページをWebに公開できる機能があります。編集したものをそのまま公開できて、とても便利です。

これを用いてページを公開して、例えば任意の画像のURLを確認してみると、以下のようになっています。

https://myspace.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2xxxxxxxx-xxxx~~%2xxxxxxxx-xxxx~~%2FUntitled.png?table=block&id=block-no-id&spaceId=space-no-id&width=670&~~~

となります。クエリパラメータにwidthが含まれているので、これを利用することができれば、画像サイズもいい感じになりそうです。

作者のotoyoさんのブログを参照すると、ファイルについてはNotion APIからblock idを用いてpublic/notion/以下にダウンロードしていることがわかりました。Imageもこのファイルの一種として取り扱っているようです。

ここでNotion APIのFile Objectを参照してみます。

Notion APIが返してくるFileに関するURLは

{
  "type": "file",
  "file": {
    "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7b8b0713-dbd4-4962-b38b-955b6c49a573/My_test_image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20221024%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221024T205211Z&X-Amz-Expires=3600&X-Amz-Signature=208aa971577ff05e75e68354e8a9488697288ff3fb3879c2d599433a7625bf90&X-Amz-SignedHeaders=host&x-id=GetObject",
    "expiry_time": "2022-10-24T22:49:22.765Z"
  }
}

となっているのですが、ここにサイズの情報はありません。つまり、APIアクセスではwidthの情報を取ることはできないように見えます。

こればっかりはNotion APIの仕様ということでどうしようもないので、自らサイズの指定ができるようにしました。

本当はwidthをどこかから取りたい。どこにあるんでしょうこの情報。

File Blockが取り扱えるもの

FileのブロックにはCaptionをつけることができます。

array of rich text objects text とのことですが、Captionを複数つける方法は僕にはわからず(これができれば規則をもっと定めやすそうなのですが)のため、力技で横幅を指定できる感じにしました。

今回はCaptionを以下のように指定した場合に、sizeのあとの数字をそのままwidthとして採用し、sizeに関するCaptionを削除する。という手段を取りました。

Image.astroのコードフェンス内で、Captionを分解します。

let width = ''
if (block.Image.Caption[0]?.Text?.Content) {
  let caption = block.Image.Caption[0].Text.Content;
  let match = caption.match(/^size(\d+)([\s\S]*)/);
  if (match){
    width = match[1].trim() + 'px';
    block.Image.Caption[0].Text.Content = match[2].trim();
  }
}
---
Image.astro

これを同じImage.astro内でimgタグに与える。

{ENABLE_LIGHTBOX ? (
  <a data-fslightbox href={image} data-type="image">
    <img src={image} alt="Image in a image block" {width} loading="lazy" />
  </a>
) : (
  <img src={image} alt="Image in a image block" {width} loading="lazy" />
)}
Image.astro

これによって、指定されたwidthで画像を表示することができるようになりました。

まとめ

本当はNotionで書いているものと同じ広さで指定できるといいのにな〜と思いつつ、現状のAPIではそのデータを取得するのが難しそうです。

デプロイしないとサイズが正確にわからないのは不便ですが、一旦サイズ指定問題を凌ぐことはできました。めでたし。