🤨

Next.jsでpublicフォルダの画像が読み込めない時の対処法

に公開

はじめに

Next.js で開発していると、public フォルダに配置した画像が読み込めないことがあります🫩

一般的な対処法を試しても解決しない場合、middleware の設定が原因かもしれません!

今回は、実際に遭遇したトラブルとその解決方法を共有します💝

基本の確認:正しい画像の読み込み方

まず、Next.js での正しい画像の読み込み方を確認しましょう。

public/
└── avatar.png
└── background.jpg

このような構成の場合、src には以下のように記述します:

<Image
  alt="avatar"
  src="/avatar.png" // publicフォルダは省略する
  width={200}
  height={200}
/>

public フォルダは省略して、ルートパス(/)から記述するのが基本的なルールですよね🕺

問題:一般的な対処法でも解決しない

しかし、正しく記述していても画像が表示されない場合があります🤨

以下を試してみても効果がない...

  • パスの記述を確認
  • ファイル名・拡張子の確認
  • キャッシュのクリア
  • 再ビルド

応急処置:unoptimized オプション

不思議なことに、unoptimized プロパティを追加すると表示されることがあります。

<Image
  alt="avatar"
  src="/avatar.png"
  width={200}
  height={200}
  unoptimized // これを追加すると表示される
/>

unoptimized を付与すると表示されるのは、画像が _next フォルダ以下ではなく、
_next と同階層に直接コピーされるためです。

しかし、これは画像最適化が無効になるため根本的な解決ではありません💩

原因:middleware の matcher 設定

調査した結果、middleware の matcher 設定が原因でした🌞!!!

画像が _next フォルダにコピーされていない状況で、middleware が画像ファイルへのリクエストをインターセプトしていたようです…

解決方法

本来 _next/image を指定しているため画像は除外されるはずですが、PWA を設定している影響なのか上手く除外されないため、画像の拡張子を明示的に追加する必要がありました🦧

middleware の matcher 設定を以下のように修正します:

修正前:

export const config = {
  matcher: "/((?!api|_next|static|_next/image|favicon.ico|background.jpg).*)",
};

修正後:

export const config = {
  matcher:
    "/((?!api|_next|static|_next/image|favicon.ico|.*\\.jpg|.*\\.png).*)",
};

変更内容

  • プロジェクト固有の background.jpg 指定を削除
  • .*\\.jpg|.*\\.png など画像拡張子を明示的に追加

これにより、画像ファイルへのリクエストが middleware を通らず、正常に表示されるようになります💘

まとめ

Next.js で画像が表示されない場合は、以下の順番で確認してみてください:

  1. 基本的な記述方法の確認 - src="/filename.jpg" 形式で記述
  2. ファイルの存在確認 - public フォルダに正しく配置されているか
  3. middleware の設定確認 - matcher で画像ファイルが除外されているか

特に middleware を使用している場合は、画像ファイルの拡張子を適切に除外設定することが重要です✨

同様の問題でお困りの方の参考になれば嬉しく思います🙌!!!

Discussion