How to Fix: next/image 报错
next/image 报错的根因与修复:为什么图片组件在 Next.js 中突然不可用
这个问题通常不是 next/image 组件本身坏了,而是图片来源、构建配置、静态资源路径或运行环境与 Next.js 图片优化机制 不匹配,最终触发编译报错、运行时报错,或者图片请求直接失败。
Understanding the Root Cause
next/image 和普通的 img 标签不同,它不是简单输出一个图片地址,而是会经过 Next.js Image Optimization 处理。也就是说,Next.js 会在编译或运行阶段检查你的图片来源是否合法、路径是否正确、尺寸信息是否完整。
结合这类问题的典型现象,报错一般集中在以下几类:
- 图片路径不合法:例如把本地图片写成了错误的相对路径,或者资源并不在
public目录下。 - 远程域名未配置:如果
src是远程图片地址,必须在next.config.js中通过 images.domains 或 images.remotePatterns 白名单放行。 - 缺少 width / height:旧写法中,
next/image通常要求明确宽高,除非你使用了特定布局模式。 - 静态导入方式错误:某些场景下,图片应使用 import 导入,而不是随意拼接字符串路径。
- 资源服务器不兼容:如果图片来自不支持优化请求的源站,Next.js 的图片优化接口可能返回错误。
- 版本差异:不同版本的 Next.js 对 Image 组件 配置项、属性命名和行为存在差异。
最关键的一点是:next/image 对图片来源的约束比 img 严格得多。因此项目里“普通 img 能显示,但 next/image 报错”是非常常见的现象。
Step-by-Step Solution
下面按排查优先级给出修复方案。建议你按顺序检查。
1. 先确认图片是本地资源还是远程资源
如果你的图片放在项目本地,推荐放入 public 目录,例如:
public/images/avatar.png
然后这样使用:
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/images/avatar.png"
alt="avatar"
width={200}
height={200}
/>
)
}
不要把路径写成类似下面这种不稳定的相对路径:
<Image src="../../assets/avatar.png" alt="avatar" width={200} height={200} />
如果图片不在 public 中,而是位于源码目录中,则使用静态导入:
import Image from 'next/image'
import avatar from '../assets/avatar.png'
export default function Page() {
return <Image src={avatar} alt="avatar" />
}
2. 如果是远程图片,配置 next.config.js
如果你的图片地址来自第三方站点、对象存储、CDN 或接口返回的完整 URL,则必须配置白名单。
推荐使用较新的 remotePatterns:
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
pathname: '/**',
},
{
protocol: 'https',
hostname: 'img.example-cdn.com',
pathname: '/**',
},
],
},
}
module.exports = nextConfig
如果你的项目版本较旧,也可能使用:
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
domains: ['example.com', 'img.example-cdn.com'],
},
}
module.exports = nextConfig
修改后务必重启开发服务:
npm run dev
3. 检查是否传入了合法的 width 和 height
很多报错来自于 缺失尺寸参数。标准写法如下:
import Image from 'next/image'
export default function Banner() {
return (
<Image
src="/images/banner.jpg"
alt="banner"
width={1200}
height={600}
/>
)
}
如果你想做响应式布局,可以配合 sizes 使用,而不是省略必要属性:
import Image from 'next/image'
export default function Hero() {
return (
<Image
src="/images/hero.jpg"
alt="hero"
width={1200}
height={800}
sizes="100vw"
/>
)
}
4. 如果图片源不适合优化,临时关闭优化验证
某些测试环境、内网地址或特殊图片服务与 Next.js 默认优化流程不兼容,可以先验证是否是优化链路引发的问题:
import Image from 'next/image'
export default function Test() {
return (
<Image
src="https://example.com/test.png"
alt="test"
width={300}
height={200}
unoptimized
/>
)
}
如果加上 unoptimized 后恢复正常,说明问题大概率在 图片优化服务、远程源站响应头、格式兼容性 或白名单配置上。
5. 检查 App Router / Pages Router 下的导入方式
无论你使用的是 App Router 还是 Pages Router,正确导入方式都应是:
import Image from 'next/image'
不要误写成其他路径,也不要和浏览器原生图片组件混用导致属性不匹配。
6. 核对实际图片地址是否能直接访问
如果是远程图片,把图片链接直接复制到浏览器中测试。重点检查:
- 是否返回 200
- 是否被鉴权拦截
- 是否发生了 302/403/404
- 是否返回的其实不是图片,而是一段 HTML 错误页
如果源站本身不可访问,next/image 自然也无法完成优化。
7. 一份可直接参考的正确配置示例
import Image from 'next/image'
export default function Demo() {
return (
<div>
<h1>Image Demo</h1>
<Image
src="/images/local-demo.png"
alt="local image"
width={400}
height={240}
/>
<Image
src="https://img.example-cdn.com/demo.png"
alt="remote image"
width={400}
height={240}
/>
</div>
)
}
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'img.example-cdn.com',
pathname: '/**',
},
],
},
}
module.exports = nextConfig
Common Edge Cases
- 开发环境正常,生产环境报错:生产环境可能开启了不同的域名、CDN、反向代理或环境变量,导致图片真实来源和本地不一致。
- 接口返回的图片 URL 是动态域名:例如测试、预发、正式环境域名不同,这时需要统一纳入 remotePatterns。
- 图片 URL 带签名参数:某些对象存储的临时授权链接虽然能访问,但如果域名没配置,依然会被拦截。
- 把 background-image 的思路直接套到 next/image:Image 组件 更适合内容图片,不适合所有背景图场景。
- 路径大小写问题:在 Windows 开发正常,但部署到 Linux 后因文件名大小写不一致导致 404。
- 使用 basePath 或 assetPrefix:如果项目配置了子路径部署,静态资源引用方式需要同步调整。
- SVG 特殊处理:某些 SVG 使用 img 或内联方案更合适,尤其在需要脚本、样式或复杂交互时。
- 旧版属性失效:升级 Next.js 后,历史属性或写法可能已变更,需对照当前版本文档。
FAQ
1. 为什么 img 标签能显示,next/image 却报错?
因为 img 只是直接请求图片,而 next/image 会先进行来源校验和优化处理。只要域名未白名单、路径不规范或尺寸缺失,就可能报错。
2. 远程图片一定要配 next.config.js 吗?
是的,绝大多数情况下必须配置。否则 Next.js 无法确认该远程资源是否允许进入 图片优化管道。
3. 加了 unoptimized 就好了,是否可以一直这么用?
可以作为临时绕过方案,但不建议长期滥用。因为这样会失去 自动优化、尺寸裁剪、性能收益。更稳妥的做法是修正远程域名配置或图片源问题。
如果你正在排查这个仓库里的问题,最优先检查的就是:图片 src 的实际值、是否为远程地址、next.config.js 是否配置 images 白名单、以及 width/height 是否完整。这四项通常就能定位绝大多数 next/image 报错 问题。
进一步参考可查看 Next.js Image 官方文档,以及问题中提供的 复现仓库 进行逐项比对。