2026-02-28

【ブログ】Cloudflare Imagesのvariantsを利用する

 このブログでは、画像のホスティングサービスとしてCloudflare Imagesを利用している。
 これまではサイズの大きい画像を事前に縮小してからアップロードしていたが、Cloudflare Imagesに「variants」という機能があることを最近知った。

variants

 variantsとは、アップロードした画像に対して、あらかじめ指定したリサイズ設定を適用して配信できる機能である。
 デフォルトでは「public」というVariantが用意されており、画像は /public パスで取得できる。例えば hoge というVariantを作成した場合、その画像は /hoge パスで取得できる。

 今回はブログ掲載用として、横幅1200pxに調整するVariantを追加する。縦横比については、アップロード前に調整しておく想定とする。

contentというVariantを追加した。
 Heightを指定しなければ、縦横比を維持したままリサイズされる。
 Fitは Scale down を選択した。これは、横幅1200px未満の画像がアップロードされた場合に拡大されないようにするためである。1200px以下の画像は、そのままのサイズで配信される。

 横幅1600pxの画像をアップロードし、デフォルトの /public と、今回作成した /content Variant で配信された画像を比較してみる。

Strapiでcontent画像を利用する

 続いて、CMSであるStrapi側の設定を変更する。
 Media Libraryはすでにカスタマイズしており、アップロード先をCloudflare Imagesに設定している。ただし、画像のURLはデフォルトでは /public パスになっているため、これを /content パスを取得するよう修正する。

 Cloudflare Images用のCustom Providerを以下のように変更する。

  export default {
    init({ baseUrl, accountId, apiToken }: InitOptions) {
      ...

      const upload = async (file: File) => {
        ...

-       file.url = responseJson.result.variants[0];
+       const firstVariantUrl = responseJson.result.variants[0];
+       const parsed = new URL(firstVariantUrl);
+       const parts = parsed.pathname.split('/'); // ['', accountHash, imageId, variant]
+       parts[parts.length - 1] = 'content';
+       parsed.pathname = parts.join('/');

        file.url = parsed.toString();
      };

 Cloudflare Imagesに画像をアップロードすると、配信可能なURLはレスポンスの result.variants 配列に含まれる。
https://developers.cloudflare.com/api/resources/images/subresources/v1/models/image/#(schema)

 今回 content Variantを新たに追加したため、配列には /public/content の2つのURLが含まれる。ただし、その順序は保証されていないようだった。そのため、いずれか1つのURLを取得し、URLの末尾にあるVariant名の部分を強制的に content に書き換える実装とした。これにより、StrapiのMedia Libraryから /content パスの画像を利用できるようになる。

 Media Library上に表示される容量やサイズは変換前(オリジナル)の情報のままだが、ひとまず今回はそのままとする。時間があるときに、表示内容をVariantに合わせる方法を検討したい。