NextJS 14(App Router+Src目录)静态资源无法访问求助
解决Next.js 14 App Router(Src目录)下国际化Middleware拦截静态资源的问题
核心问题
你的国际化Middleware会将所有未带locale前缀的请求重定向到带locale的路径,但未正确排除public目录下的静态资源路径,导致图片、favicon.ico、robots.txt等资源被错误重定向,无法正常访问。
解决方案
方案1:修正Matcher规则(最简便)
修改Middleware的config.matcher,在负向预查中加入所有需要排除的静态资源路径:
export const config = { // 排除API、Next.js内置静态资源、public下的静态资源 matcher: ['/((?!api|_next/static|_next/image|img|favicon.ico|robots.txt|manifest.json).*)'], };
- 规则说明:
(?!xxx)是负向预查,表示不匹配以这些路径开头的请求:api/:接口请求_next/static/、_next/image/:Next.js内置的静态资源、图片优化路径img/:对应public/img目录下的所有图片资源favicon.ico、robots.txt、manifest.json:根目录下的静态配置文件
方案2:Middleware内手动放行静态资源(更可靠)
恢复并扩展你注释掉的静态资源排除逻辑,直接放行不需要国际化的静态资源:
export function middleware(request: NextRequest) { const pathname = request.nextUrl.pathname; // 直接放行所有静态资源,避免被重定向 const staticAssetPaths = [ '/favicon.ico', '/robots.txt', '/manifest.json', '/img/', // 匹配public/img下的所有文件 // 可添加其他静态资源路径,如/svg/、/fonts/等 ]; if (staticAssetPaths.some(path => pathname.startsWith(path))) { return NextResponse.next(); } // 原有国际化逻辑(建议替换硬编码的locale为自动匹配值) const pathnameIsMissingLocale = i18n.locales.every( (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}` ); if (pathnameIsMissingLocale) { // 使用getLocale函数自动获取用户偏好语言,而非硬编码'id' const locale = getLocale(request) || i18n.defaultLocale; return NextResponse.redirect( new URL( `/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname}`, request.url ) ); } }
- 优化点:将硬编码的
'id'替换为getLocale(request),让国际化逻辑更符合预期,自动匹配用户浏览器偏好语言。
验证步骤
- 重启Next.js开发服务器
- 直接访问静态资源,如
http://localhost:3000/img/your-image.png、http://localhost:3000/favicon.ico - 确认请求未被重定向到带
/id/前缀的路径,资源能正常加载
内容的提问来源于stack exchange,提问作者Agus Dwi Milniadi
相关产品推荐
相关产品推荐

