Nuxt3で外部画像を静的生成する

公開日:2023/7/29更新日:2023/8/8

Nuxt3で内部画像と外部画像を静的生成し、各デバイス毎に画像サイズを最適化するには、公式モジュールのNuxt Imageを使います。

セットアップ

以下のコマンドでインストールします。

npm install -D @nuxt/image@rc

nuxt.config.tsファイルのmodules@nuxt/imageを追加します。外部から配信される画像を静的生成する場合はimagedomainsに配信元のドメインを配列で追加します。

export default defineNuxtConfig({
  modules: ["@nuxt/image"],
  image: {
    domains: ["example.com"],
  },
});

以上でセットアップは完了です。

コンポーネントとして使う

通常の<img />タグと同じように使う場合は、<NuxtImg />コンポーネントを使います。

<NuxtImg src="/sample.jpg" alt="" :width="1200" :height="800" />

デバイス毎に最適化した画像を配信する場合は、sizes属性を追加すると、生成後の画像に自動的にsrcsetが設定されるので便利です。

<NuxtImg
  src="/sample.jpg"
  alt=""
  :width="1200"
  :height="800"
  sizes="sm:100vw md:50vw lg:400px"
/>

sizesを設定するのが面倒な場合は、<NuxtPicture>コンポーネントを使うのもアリです。自動的に各デバイス毎の画像を生成して配信してくれます。

<NuxtPicture>コンポーネントにはwebpavifなど次世代の拡張子が使える特徴もありますが、執筆時点のバージョン(1.0.0-rc.1)では、サイズがダウンしているだけで拡張子は元の画像のままでした。

データを取得して使う

HTMLデータをパースして使う場合など、コンポーネントをそのまま使うのではなく、srcsetsizsesなどのデータを使って画像を表示する場合は、useImage()コンポーザブルを使います。

例として、WP REST APIから本文を取得してCheerioでパース、元の画像を静的画像に置き換える関数は以下の通りです。

import { load } from "cheerio";

export default function (rawHtml: string) {
  const $ = load(rawHtml);
  const nuxtImg = useImage();

  $("figure img").each((_, img) => {
    const { src, srcset, sizes } = nuxtImg.getSizes(img.attribs.src, {
      sizes: "xs:100vw sm:100vw md:100vw lg:100vw xl:100vw",
      modifiers: {
        quality: 70,
      },
    });
    $(img).attr("src", src);
    $(img).attr("srcset", srcset);
    $(img).attr("sizes", sizes);
  });

  return $.html();
}