【Astro v4】Notion APIの画像(S3)を、リンク切れさせずに爆速表示する方法

はじめに

NotionをヘッドレスCMSとして使うと、「画像のリンク切れ問題」 に必ず直面します。 Notion APIから返ってくる画像のURL(AWS S3)には有効期限があり、約1時間でアクセスできなくなるからです。

静的サイト生成(SSG)の場合、ビルドして1時間後にサイト上の画像がすべて「Access Denied」になってしまいます。

この記事では、Astro v4の astro:assets 機能 を使って、この画像をビルド時にダウンロード&永続化し、さらにWebPに変換して爆速表示する方法を紹介します。


やること

  1. Astroの設定で、Notionの画像ドメインを許可する。
  2. <Image /> コンポーネントを使って表示する。

たったこれだけで、Astroが裏側で「画像のダウンロード」「リサイズ」「フォーマット変換」を全部やってくれます。

1. astro.config.mjs の設定

Notionの画像は prod-files-secure.s3.us-west-2.amazonaws.com などのドメインから配信されます。 Astroがこれらの外部画像を処理できるように、remotePatterns を追加します。

javascript
import { defineConfig } from 'astro/config';

export default defineConfig({
  image: {
    domains: ['prod-files-secure.s3.us-west-2.amazonaws.com'],
    // または remotePatterns で詳細に指定
    remotePatterns: [{
      protocol: 'https',
      hostname: '**.amazonaws.com',
    }],
  },
  // ...その他の設定
});

2. 画像コンポーネントの実装

標準の <img> タグの代わりに、Astroの <Image /> を使います。

plain text
---
import { Image } from 'astro:assets';

interface Props {
  src: string; // Notionから取得した画像URL
  alt: string;
}

const { src, alt } = Astro.props;
---

<!--
  inferSize: true にすると、リモート画像のサイズを自動取得してくれます。
  format: 'webp' でWebPに変換します。
-->
<Image
  src={src}
  alt={alt}
  width={800}
  height={450}
  format="webp"
  class="rounded-lg shadow-md"
/>

結果どうなるか?

ビルドコマンド(npm run build)を実行すると、Astroは以下のように動きます。

  1. NotionのS3 URLにアクセスして画像をダウンロードする。
  2. 画像をWebP形式に変換し、指定サイズにリサイズする。
  3. 生成された画像を dist/_astro/ フォルダに保存する。
  4. HTMLの src をローカルのパス(永続化されたパス)に書き換える。

これにより、Notion側のURL有効期限が切れても、サイト上の画像は永遠に表示され続けます。 しかもファイルサイズが数MB→数十KBに圧縮されるので、Lighthouseのスコアも爆上がりします。


まとめ

「Notionの画像が表示されない…」と悩んでいる方は、自前でダウンロードスクリプトを書く前に、Astro標準の画像最適化を試してみてください。

紹介

この画像最適化フローを標準搭載したブログ構築キット 『Astro Notion Edge』 をOSSで公開しました。 設定済みの環境ですぐにブログを始めたい方は、ぜひGitHubをチェックしてみてください!

Image

https://t.co/bzNf7SwuyK