Next.js Image optimizationエラーの原因と解決方法
Next.jsを使用してWeb開発を行う際、Image optimizationに関連するエラーに直面することがあります。このエラーは初心者にとって特に戸惑いやすい問題です。本記事では、Next.jsのImage optimizationエラーが発生する原因から、具体的な解決手順、そしてよくある間違いまで、詳しく解説していきます。
Next.js Image optimizationエラーの原因
Next.jsは、<Image>コンポーネントを提供しており、自動的に画像を最適化します。このImage optimizationは非常に強力な機能ですが、適切に使用しないとエラーが発生します。主な原因を以下に説明します。
1. 必須プロパティの不足
<Image>コンポーネントを使用する際、src、alt、width、heightプロパティは必須です。これらのいずれかが欠けると、エラーが発生します。特に初心者は、HTML標準の<img>タグと混同しやすい点です。
2. 外部URL画像の設定不足
外部URLから画像を読み込む場合、next.config.jsで許可するドメインを登録する必要があります。設定がないと、セキュリティエラーが発生します。
3. 画像サイズの不一致
widthとheightで指定したサイズが実際の画像サイズと大きく異なる場合、レイアウトシフトが発生し、最適化が機能しません。
4. next/imageのインポート漏れ
<Image>コンポーネントをインポートし忘れると、参照エラーが発生します。
エラー解決の実装手順
ステップ1:next/imageからImageコンポーネントをインポート
まず、Next.jsの公式Image コンポーネントを正しくインポートします。
'use client';
import Image from 'next/image';
export default function MyComponent() {
return (
<Image
src="/images/sample.jpg"
alt="サンプル画像"
width={400}
height={300}
/>
);
}
このステップで重要な点は、from 'next/image'という正確なインポート文を使うことです。他のImage コンポーネントライブラリと混同しないよう注意してください。
ステップ2:ローカル画像の配置
プロジェクト内の公開フォルダ(publicフォルダ)に画像を配置します。
project/
├── public/
│ └── images/
│ ├── sample.jpg
│ └── logo.png
├── pages/
├── components/
└── next.config.js
publicフォルダに配置した画像は、ブラウザから直接アクセス可能になります。srcプロパティには、/images/sample.jpgのようにスラッシュから始まるパスを指定します。
ステップ3:外部URLの場合、next.config.jsを設定
外部URLから画像を読み込む場合は、next.config.jsでドメインを許可する必要があります。
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
port: '',
pathname: '/images/**',
},
{
protocol: 'https',
hostname: '*.unsplash.com',
port: '',
},
],
},
};
module.exports = nextConfig;
remotePatternsは複数のドメインをサポートしており、ワイルドカード(*)を使用したパターンマッチングも可能です。
ステップ4:width と height を適切に指定
静的な画像の場合、widthとheightを実際の画像サイズで指定します。
import Image from 'next/image';
import sampleImage from '@/public/images/sample.jpg';
export default function ImageComponent() {
return (
<Image
src={sampleImage}
alt="最適化された画像"
// staticインポートを使用する場合、widthとheightは自動推定される
priority
/>
);
}
静的インポートを使用すると、Next.jsが自動的に画像のサイズを検出するため、エラーを避けられます。
実践的なコード例
例1:ローカル画像の基本的な使用
'use client';
import Image from 'next/image';
export default function ProfileCard() {
return (
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
<Image
src="/images/profile.jpg"
alt="プロフィール画像"
width={100}
height={100}
style={{ borderRadius: '50%' }}
/>
<div>
<h2>ユーザー名</h2>
<p>ここに説明文が入ります</p>
</div>
</div>
);
}
例2:動的なURL画像の読み込み
'use client';
import Image from 'next/image';
import { useState } from 'react';
export default function DynamicImage() {
const [imageUrl, setImageUrl] = useState('https://example.com/image1.jpg');
return (
<div>
<Image
src={imageUrl}
alt="動的画像"
width={500}
height={400}
loader={({ src }) => src}
/>
<button onClick={() => setImageUrl('https://example.com/image2.jpg')}>
画像を変更
</button>
</div>
);
}
動的なURLの場合、loaderプロップを使用してカスタムローダーを定義できます。
例3:レスポンシブ画像の実装
'use client';
import Image from 'next/image';
import { useState, useEffect } from 'react';
export default function ResponsiveImage() {
const [isLarge, setIsLarge] = useState(false);
useEffect(() => {
const handleResize = () => {
setIsLarge(window.innerWidth > 768);
};
handleResize();
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<Image
src="/images/responsive.jpg"
alt="レスポンシブ画像"
width={isLarge ? 1200 : 600}
height={isLarge ? 800 : 400}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
);
}
例4:複数画像を管理する場合
'use client';
import Image from 'next/image';
const images = [
{ id: 1, src: '/images/img1.jpg', alt: '画像1' },
{ id: 2, src: '/images/img2.jpg', alt: '画像2' },
{ id: 3, src: '/images/img3.jpg', alt: '画像3' },
];
export default function ImageGallery() {
return (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '1rem' }}>
{images.map((image) => (
<Image
key={image.id}
src={image.src}
alt={image.alt}
width={300}
height={300}
style={{ objectFit: 'cover' }}
/>
))}
</div>
);
}
よくある間違いと対策
間違い1:HTMLのタグを使い続ける
誤ったコード:
// ❌ 避けるべき
export default function MyComponent() {
return <img src="/images/sample.jpg" alt="サンプル" />;
}
正しいコード:
// ✅ 推奨
import Image from 'next/image';
export default function MyComponent() {
return (
<Image
src="/images/sample.jpg"
alt="サンプル"
width={400}
height={300}
/>
);
}
HTMLの標準<img>タグは最適化されないため、Next.jsの利点を活かせません。
間違い2:外部URLを許可なく使用
誤ったコード:
// ❌ エラーが発生します
export default function MyComponent() {
return (
<Image
src="https://external-domain.com/image.jpg"
alt="外部画像"
width={400}
height={300}
/>
);
}
正しいコード:
// next.config.jsで許可を追加
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'external-domain.com',
},
],
},
};
module.exports = nextConfig;
間違い3:fill propsの誤解
レスポンシブ画像でfillプロップを使用する際、親要素にposition: relativeが必要です。
誤ったコード:
// ❌ レイアウトが崩れる
export default function MyComponent() {
return (
<div>
<Image
src="/images/sample.jpg"
alt="サンプル"
fill
/>
</div>
);
}
正しいコード:
// ✅ 正しいレイアウト
export default function MyComponent() {
return (
<div style={{ position: 'relative', width: '100%', height: '500px' }}>
<Image
src="/images/sample.jpg"
alt="サンプル"
fill
style={{ objectFit: 'cover' }}
/>
</div>
);
}
間違い4:widthとheightの型エラー
誤ったコード:
// ❌ 文字列を指定するとエラー
<Image
src="/images/sample.jpg"
alt="サンプル"
width="400"
height="300"
/>
正しいコード:
// ✅ 数値で指定
<Image
src="/images/sample.jpg"
alt="サンプル"
width={400}
height={300}
/>
間違い5:優先度の設定忘れ
ページ上で最初に見える重要な画像にはpriorityプロップを追加するべきです。
推奨コード:
// ✅ ヒーロー画像には priority を付与
<Image
src="/images/hero.jpg"
alt="ヒーロー画像"
width={1200}
height={600}
priority
/>
トラブルシューティング
エラー:”Cannot find image file”
原因:画像ファイルがpublicフォルダに存在しない、またはパスが間違っています。
解決方法:
- ファイルが
publicフォルダ内に実際に存在することを確認 - パスがスラッシュで始まることを確認:
/images/sample.jpg - ファイル名の大文字小文字を区別するOSの場合、正確に一致していることを確認
エラー:”Domain not configured”
原因:外部URLを使用しているが、next.config.jsに許可されていません。
解決方法:next.config.jsにremotePatternsを追加します。
エラー:”Image with src \”..\” must use width and height”
原因:widthまたはheightが指定されていません。
解決方法:必ず両方のプロップを数値で指定してください。
まとめ
Next.jsのImage optimizationエラーは、正しい使用方法を理解すれば簡単に解決できます。本記事では以下の重要なポイントをカバーしました:
- 必須プロップの理解:
src、alt、width、heightはすべて必須です - インポート方法:
from 'next/image'から正確にインポート - ローカル画像:
publicフォルダに配置し、スラッシュから始まるパスを使用 - 外部URL画像:
next.config.jsでドメインを許可 - レスポンシブ対応:
fillプロップまたはsizes属性を活用 - よくある間違い:HTMLの
<img>タグとの混同、型エラー、親要素のスタイル設定
これらのガイドラインに従うことで、Next.jsの画像最適化機能を最大限に活用でき、高速で効率的なWebアプリケーションを構築できます。エラーが発生した場合は、まず本記事のトラブルシューティングセクションを参照し、段階的に問題を解決してください。
Next.jsを継続的に学習し、最新のドキュメントを確認することも重要です。公式ドキュメントは常に更新されており、新機能や改善内容が追加されています。

