NextJS发布到GitHub Pages后路由跳转public图片不渲染问题
问题根因
这个图片加载异常的核心原因是原生img标签的相对路径解析规则和Next.js子路径部署的适配逻辑不匹配,不存在未知诱因:
- 你当前写的
src='Avatar.png'是相对路径,浏览器解析这类路径时,会默认以当前页面URL的目录层级作为基准拼接资源地址 - 首次访问带末尾
/的站点地址时,浏览器判定当前目录是/personal-portfolio/,拼接后的资源地址为/personal-portfolio/Avatar.png,正好命中public目录下的静态文件,因此可以正常加载 - 站内通过next/link跳转回不带末尾
/的地址时,浏览器会把URL最后一段的personal-portfolio识别为具体文件而非目录,此时解析基准变成站点根路径/,拼接后的资源地址为/Avatar.png,完全匹配不到部署在子路径下的静态资源,自然加载失败 - 右下角悬浮按钮的同一张图片始终正常加载,本质是因为它的src使用了固定前缀的绝对路径,不会随当前页面URL变化改变解析结果
- 你之前推测的「未使用next/image组件导致路径未自动适配路由前缀」是完全正确的:原生img标签不会自动读取Next.js配置中的
basePath参数,只有框架封装的next/image、next/link这类内置组件会自动完成前缀拼接。
修复方案
不需要用「将about.js改为独立页面」这类规避性方案,任选以下一种方式即可彻底解决问题:
方案1:写死带项目前缀的根绝对路径(零依赖改造成本最低)
直接把img标签的src改为从站点根目录开始的绝对路径,带上你配置的自定义路由前缀即可:
// components/about.js <div className={styles['avatar-container']}> <img className={styles['avatar-img']} src='/personal-portfolio/Avatar.png' width="188px" height="196px" alt="a picture of Yu-Ming" /> </div>
注意路径开头必须加
/,这样无论当前页面URL结构如何变化,浏览器都会固定从站点根目录下的personal-portfolio路径查找资源,不会再出现相对路径拼接错误。这也是你之前测试「用absolute path临时解决」生效的核心原理。
方案2:替换为官方next/image组件(长期维护推荐)
将原生img标签替换为Next.js内置的Image组件,组件会自动读取basePath配置拼接资源地址,后续就算修改路由前缀,也不需要挨个调整静态资源路径:
首先在组件顶部引入Image组件,再修改渲染逻辑即可,public目录下的静态资源直接写根路径就能被正确识别:
// 组件顶部引入 import Image from 'next/image' // components/about.js 渲染部分 <div className={styles['avatar-container']}> <Image className={styles['avatar-img']} src='/Avatar.png' width={188} height={196} alt="a picture of Yu-Ming" /> </div>
方案3:统一路由末尾斜杠规则
如果不想修改现有资源路径,也可以通过Next.js配置强制所有路由跳转后自动补充末尾斜杠,保证首次访问和站内跳转的URL结构完全一致,相对路径的解析基准就不会出现偏差。配置方式为在next.config.js中添加如下参数:
/** @type {import('next').NextConfig} */ const nextConfig = { // 保留原有自定义前缀配置 basePath: '/personal-portfolio', // 新增配置:所有路由自动补末尾斜杠 trailingSlash: true, } module.exports = nextConfig
内容的提问来源于stack exchange,提问作者ChillDiver
相关产品推荐
相关产品推荐

