😇

middleware.tsの設定をすると画像を表示できない?

2024/11/18に公開

起きている現象

📁public/assets/ディレクトリに配置した画像を表示できなくなってしまった?

error log

GET /about 200 in 271ms
 ✓ Compiled /not-found in 48ms (385 modules)
 ✓ Compiled /_not-found in 63ms (689 modules)
 GET /assets/jboy.png 404 in 129ms
 ⨯ The requested resource isn't a valid image for /assets/jboy.png received text/html; charset=utf-8

画像のパスの問題ですね。Next.jsでは画像ファイルは通常 public ディレクトリに配置する必要があります。また、middlewareの設定で画像へのアクセスがブロックされている可能性もあります。

これを修正しましょう:

  1. まず、画像ファイルの配置を確認します:
  • 画像を public/assets/jboy.png に移動してください。
  1. middlewareの設定を修正します:
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const isAuthenticated = () => {
  return true
}

const protectedRoutes = ['/home']
const publicRoutes = ['/', '/about']

// not-foundページ自体はチェックから除外する必要があります
const systemRoutes = ['/not-found']

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl

  // 画像やその他の静的ファイルへのアクセスはスキップ
  if (pathname.startsWith('/assets/') || 
      pathname.startsWith('/_next/') || 
      pathname.includes('.')) {
    return NextResponse.next()
  }

  // システムルートはチェックをスキップ
  if (systemRoutes.includes(pathname)) {
    return NextResponse.next()
  }

  // 404ページの処理
  const validRoutes = [...protectedRoutes, ...publicRoutes]
  if (!validRoutes.includes(pathname)) {
    // not-foundページを表示
    return NextResponse.rewrite(new URL('/not-found', request.url))
  }

  // 認証が必要なルートのチェック
  if (protectedRoutes.includes(pathname)) {
    const isAuthed = isAuthenticated()
    
    if (!isAuthed) {
      return NextResponse.redirect(new URL('/about', request.url))
    }
  }

  return NextResponse.next()
}

export const config = {
  matcher: [
    // 静的ファイルと API ルートを除外
    '/((?!api|_next/static|_next/image|assets|favicon.ico).*)',
  ]
}

  1. 画像を使用するコンポーネントでは、Next.jsの Image コンポーネントを使用することを推奨します:
// app/about/page.tsx
import Image from 'next/image'

export default function About() {
  return (
    <div>
      {/* Next.js Image componentを使用する場合 */}
      <Image
        src="/assets/jboy.png"  // publicディレクトリからの相対パス
        alt="Jboy"
        width={500}  // 適切なサイズに調整してください
        height={300} // 適切なサイズに調整してください
      />

      {/* 通常のimg要素を使用する場合 */}
      {/* <img src="/assets/jboy.png" alt="Jboy" /> */}
    </div>
  )
}

  1. 必要に応じて next.config.js で画像の設定を追加:
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    domains: [], // 外部画像を使用する場合はここにドメインを追加
  },
}

module.exports = nextConfig

確認すべきポイント:

  1. ファイル構造が以下のようになっているか確認:
your-project/
├── public/
│   └── assets/
│       └── jboy.png
├── app/
│   ├── about/
│   │   └── page.tsx
│   └── not-found.tsx
├── middleware.ts
└── next.config.js
  1. 画像へのパス指定が正しいか確認:
  • public ディレクトリ内の画像は、ルートパスから参照します
  • 例:public/assets/jboy.png/assets/jboy.png
  1. 開発サーバーを再起動:
npm run dev

これらの変更を適用することで、画像が正しく表示されるはずです。また、Next.jsの Image コンポーネントを使用することで、自動的な画像の最適化や遅延読み込みなどの恩恵も受けられます。

Discussion