😇
middleware.tsの設定をすると画像を表示できない?
起きている現象
📁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の設定で画像へのアクセスがブロックされている可能性もあります。
これを修正しましょう:
- まず、画像ファイルの配置を確認します:
- 画像を
public/assets/jboy.png
に移動してください。
- 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).*)',
]
}
- 画像を使用するコンポーネントでは、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>
)
}
- 必要に応じて
next.config.js
で画像の設定を追加:
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
domains: [], // 外部画像を使用する場合はここにドメインを追加
},
}
module.exports = nextConfig
確認すべきポイント:
- ファイル構造が以下のようになっているか確認:
your-project/
├── public/
│ └── assets/
│ └── jboy.png
├── app/
│ ├── about/
│ │ └── page.tsx
│ └── not-found.tsx
├── middleware.ts
└── next.config.js
- 画像へのパス指定が正しいか確認:
- public ディレクトリ内の画像は、ルートパスから参照します
- 例:
public/assets/jboy.png
→/assets/jboy.png
- 開発サーバーを再起動:
npm run dev
これらの変更を適用することで、画像が正しく表示されるはずです。また、Next.jsの Image
コンポーネントを使用することで、自動的な画像の最適化や遅延読み込みなどの恩恵も受けられます。
Discussion