https://manj.io/blog/notion-blog-custom-3 の続き
オリジナルのnotion-blogは記事内の画像を表示するときに
api/asset
へquery paramとしてそのurlとblockidを付与したものを挿入api/asset
の処理として、notion-blog内でその画像URLの閲覧権限を取得しquery paramに付加して307でそのURLに転送させるというまわりくどい方式を使っている。
こうすると毎回リダイレクトが走る、つまり毎回北米リージョンのs3から画像を取得しなきゃいけない。さらに、Vercelが提供してるCDNにもキャッシュされないので、体験が悪い。
なんでVercelはこんな実装をしたんだろうか。自サービスのCDNになるべく載せたくないみたいなアレか? まあHobbyで無料使用してる上にnotion-blogというおもちゃまで提供してもらってる身なのでノーコメント。Vercelは最高です。
さて、解決策としてasset.ts
内の処理を「内部でs3から画像を取得してそのデータを返す」ように変更した。
[slug].tsx
では以下のように変更。api/asset?~
からapi/asset/[blockid]
に変更しただけ。これはパスが特定されないとCDNに載らないんじゃないかと思ったからだけど、どうやらそうでもないように見えるので無駄かもしれない。<Img>
はnext/image
を使ってる。lazy-loadできるらしい。
pages/api/asset/[blockid].ts
を新しく作った。生成した認証情報つきurlへfetch()
して、レスポンスのblobをbufferに変換している。ついでにキャッシュ用のヘッダもつけた。
max-age
が長すぎる説はあるけど、blockidの変更によってURLが変わるので、Notion内で画像を変更することでクライアント側のキャッシュを雑に無効化することができる。ということでとりあえず2時間。別に1年でもいいはずだけど、ブラウザ側にキャッシュを長時間置くことを強いるのもあんまり行儀がよろしくない気がしている。
コードは以下。
こうすることで、画像が無事VercelのCDNに載るようになった。
これからやりたいことリスト: