【Astro v4】Notion APIの画像(S3)を、リンク切れさせずに爆速表示する方法
はじめに
NotionをヘッドレスCMSとして使うと、「画像のリンク切れ問題」 に必ず直面します。 Notion APIから返ってくる画像のURL(AWS S3)には有効期限があり、約1時間でアクセスできなくなるからです。
静的サイト生成(SSG)の場合、ビルドして1時間後にサイト上の画像がすべて「Access Denied」になってしまいます。
この記事では、Astro v4の astro:assets 機能 を使って、この画像をビルド時にダウンロード&永続化し、さらにWebPに変換して爆速表示する方法を紹介します。
やること
- Astroの設定で、Notionの画像ドメインを許可する。
<Image />コンポーネントを使って表示する。
たったこれだけで、Astroが裏側で「画像のダウンロード」「リサイズ」「フォーマット変換」を全部やってくれます。
1. astro.config.mjs の設定
Notionの画像は prod-files-secure.s3.us-west-2.amazonaws.com などのドメインから配信されます。
Astroがこれらの外部画像を処理できるように、remotePatterns を追加します。
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 /> を使います。
---
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は以下のように動きます。
- NotionのS3 URLにアクセスして画像をダウンロードする。
- 画像をWebP形式に変換し、指定サイズにリサイズする。
- 生成された画像を
dist/_astro/フォルダに保存する。 - HTMLの
srcをローカルのパス(永続化されたパス)に書き換える。
これにより、Notion側のURL有効期限が切れても、サイト上の画像は永遠に表示され続けます。 しかもファイルサイズが数MB→数十KBに圧縮されるので、Lighthouseのスコアも爆上がりします。
まとめ
「Notionの画像が表示されない…」と悩んでいる方は、自前でダウンロードスクリプトを書く前に、Astro標準の画像最適化を試してみてください。
紹介
この画像最適化フローを標準搭載したブログ構築キット 『Astro Notion Edge』 をOSSで公開しました。 設定済みの環境ですぐにブログを始めたい方は、ぜひGitHubをチェックしてみてください!