next/image の hostname is not configured の直し方
実際に出るエラー
next/image で外部の画像を出すとき、取得先を next.config.ts に書いていないと出るエラーです。
開発と本番で、壊れ方が違う
同じコードでも、開発モードと本番で起きることがまったく違います。実機で確かめました。
import Image from 'next/image'
export default function Page() {
return <Image src="https://example.com/a.png" alt="" width={100} height={100} />
}
| 開発(next dev) | 本番(next build → start) | |
|---|---|---|
| ページ | エラーで止まる | 普通に出る |
| 画像 | — | 読み込めない(400) |
| エラーの文言 | hostname is not configured | どこにも出ない |
本番では、ビルドも通り、ページも出て、サーバーのログにも何も残りません。画像だけが静かに消えます。開発で一度も開かずに出すと、最初に気づくのは利用者です。
なぜ断られるのか
next/image は、外部の画像を自分のサーバーを経由して配ります。出来あがった HTML の img は、元の URL ではなくこうなっています(実機で確かめた形です)。
/_next/image?url=https%3A%2F%2Fexample.com%2Fa.png&w=128&q=75
- Browser/_next/image へ取りに来る
元の URL は引数として付いている。
- Server取りに行ってよい相手か確かめる
next.config.ts に書いた取得先だけ許す。書いていなければ 400。
- Server元の場所から取ってきて変換する
画面の幅に合わせた大きさと形式にして返す。
自分のサーバーが外へ取りに行く以上、相手を絞る必要があります。何でも取りに行ける状態は、自分のサーバーを他人の踏み台として貸すのと同じです。だから、書いていない取得先は断るのが既定になっています。
直し方
取得先を remotePatterns に書きます。
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
images: {
remotePatterns: [{ protocol: 'https', hostname: 'example.com' }],
},
}
export default nextConfig
必要な取得先だけを、できるだけ狭く書いてください。
unoptimized にする
images: { unoptimized: true }変換をやめる。元の大きな画像がそのまま届く。
remotePatterns に書く
images: { remotePatterns: [ { protocol: 'https', hostname: 'example.com' }, ], }
許可した相手からだけ取り、変換して配る。
unoptimized にすると、実機では img の src が元の URL そのままになりました。400 は出なくなりますが、大きさも形式も変わらないまま届きます。エラーを消すための近道として使わないでください(この問題)。
直したあとに確かめること
- 開発モードで一度開く。取得先の書き漏れはここで止まって教えてくれます
- 本番ビルドで開き、開発ツールで画像の取得が 200 かを見る
- 取得先の数と画像の量を見積もる。変換も通信も自分のサーバーの負担です
出典
- nextjs.org/docs/messages/next-image-unconfigured-host
- nextjs.org/docs/app/api-reference/components/image
このページの内容は上記の一次情報を基準に書いています。個人ブログや二次情報を根拠にしていません。