🐙

Next.js 14 から<Image>の外部ドメイン画像読み込み設定でdomainsの使用が非推奨に

2023/11/25に公開

状況

NextAuth.jsを使用してGitHubアカウントとGoogleアカウントでログインできる機能を実装していました(AppRouter環境)。ログイン自体は機能するようになったが、<img>タグでログインユーザの画像を表示していたため、next build時に警告が発生。next/imageの<Image>を使って画像を最適化すべき旨のメッセージが表示されていました。

Warning: Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element

https://nextjs.org/docs/messages/no-img-element
https://next-auth.js.org/

<Image>による外部ドメイン画像読み込み制限

<img>から<Image>に変更し、(altなどを設定して、)画像を確認してみても画像は表示されません。

<Image>にはアプリケーションをユーザーの攻撃から守るため、外部ドメインの画像読み込みを制限する機構が組み込まれており、画像を読み込むためにはnext.config.jsで画像読み込みを許可するドメインを指定する必要があります。
https://nextjs.org/docs/messages/next-image-unconfigured-host

next.config.js
module.exports = {
  images: {
        //GoogleとGitHubのアカウント画像の読み込みを許可	
    domains: [
	'lh3.googleusercontent.com',
	'avatars.githubusercontent.com'
	],
  },
}

上記の設定を追加することで、画像が読み込まれるようになり無事解決🙌
...したかに思われたのだが、再びnext build時に警告が発生。

 ⚠ The "images.domains" configuration is deprecated. Please use "images.remotePatterns" configuration instead.	

Next.js 14からdomainsの使用は一部の状況を除いて非推奨となり、代わりにremotePatternsの使用が推奨されるようになったようです。

Warning: Deprecated since Next.js 14 in favor of strict remotePatterns in order to protect your application from malicious users. Only use domains if you own all the content served from the domain.

https://nextjs.org/docs/app/api-reference/components/image#domains

next.config.js
images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'lh3.googleusercontent.com'
      },
      {
        protocol: 'https',
        hostname: 'avatars.githubusercontent.com'
      }
    ]
  }

remotePatternsを用いた設定によって、外部ドメインの画像読み込みが警告なしで行えるようになりました🥳

remotePatterns

remotePatternsでは、指定していないprotocol, hostname, portやパターンに適合しないpathなどがリクエストされた際に、400 Bad Requestを返すことで、画像読み込みを制限できるようになっているようですね。

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        port: '',
        pathname: '/account123/**',
      },
    ],
  },
}	

https://nextjs.org/docs/app/api-reference/components/image#remotepatterns

Discussion