Next.js 14(App Router)本地化后无法访问public文件夹
解决Next.js 14 App Router多语言路由下Public文件夹资源无法访问问题
问题场景
- Next.js版本:14.0.3,采用App Router
- 页面结构:主
page.tsx和layout.tsx放入src/app/[lang]文件夹,通过Prismic定义的语言生成带locale前缀的子路由(如http://localhost:3000/en-gb/*) - 使用中间件处理多语言路由跳转,将无locale前缀的路径重写到默认locale路径
- 问题:原本放在
public文件夹的静态资源(如/images/GrayArrowDown.png)无法加载,页面迁移到[lang]目录前可正常访问
问题原因
你的中间件config中的matcher规则仅排除了Next.js的_next资源目录,但未排除public文件夹下的静态资源请求。当浏览器请求/images/GrayArrowDown.png时,会被中间件匹配并重写成/${defaultLocale}/images/GrayArrowDown.png,而实际静态资源存储在根路径的public下,不存在带locale前缀的路径,因此无法找到资源。
解决方案
修改中间件的matcher规则,将静态资源路径排除在中间件处理范围之外。
修改后的middleware.tsx代码:
import { NextRequest, NextResponse } from 'next/server'; import { createClient } from '@/prismicio'; export async function middleware(request: NextRequest) { const client = createClient(); const repository = await client.getRepository(); const locales = repository.languages.map((lang) => lang.id); const defaultLocale = locales[0]; const { pathname } = request.nextUrl; const pathnameIsMissingLocale = locales.every( (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}` ); if (pathnameIsMissingLocale) { return NextResponse.rewrite( new URL(`/${defaultLocale}${pathname}`, request.url) ); } } export const config = { matcher: [ '/((?!_next|images|favicon.ico).*)', // 排除Next.js资源、images目录及favicon ], };
说明
- 若
public下还有其他静态资源目录(如fonts、icons),只需在matcher的排除列表中添加对应的路径即可,格式为|目录名 - 静态资源的引用路径保持根路径形式(如
/images/GrayArrowDown.png)即可,无需添加locale前缀
验证
修改完成后重启next dev服务,页面中的静态资源即可正常加载。
内容的提问来源于stack exchange,提问作者IDP00
相关产品推荐
相关产品推荐

