Next.js如何实现@开头动态路由 区分用户页与普通内容页
解决方案
方案一:修复现有重写配置
你当前遇到的报错是Next.js对Link组件href和as参数的结构校验不通过,同时重写规则未覆盖无后缀的根路径用户名场景,按以下步骤调整即可:
- 修改
next.config.js的重写规则,覆盖两种场景的@开头路径:
module.exports = { reactStrictMode: true, async rewrites() { return [ // 匹配带后缀的用户路径,比如/@lumen/post/123 { source: '/:username(@[a-zA-Z0-9]+)/:path*', destination: "/user/:username/:path*", }, // 匹配根路径下的纯用户名路径,比如/@lumen { source: '/:username(@[a-zA-Z0-9]+)', destination: "/user/:username", } ] } }
- 简化
Link组件写法,不需要额外加as参数,直接写对外暴露的公开路径即可,重写规则会自动做内部路径转发:
<Link href={`/@${post.author.username}`}> {post.author.username} </Link>
方案二:使用Middleware实现更稳定的路由分发
该方案优先级高于重写规则,不会出现本地正常、部署到Vercel后404的问题,更推荐生产环境使用:
- 在项目根目录(和
pages文件夹同级)新建middleware.ts文件:
import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { const { pathname } = request.nextUrl // 匹配所有@开头的用户路径 if (pathname.startsWith('/@')) { const pathSegments = pathname.split('/') const username = pathSegments[1] const restPath = pathname.slice(`/${username}`.length) || '' // 内部转发到用户页路由,地址栏路径不变 return NextResponse.rewrite(new URL(`/user/${username}${restPath}`, request.url)) } // 其他路径走默认逻辑,匹配普通内容页[pageSlug].tsx return NextResponse.next() } // 配置middleware匹配规则,排除静态资源、接口等不需要处理的路径 export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], }
- 保留
pages/[pageSlug].tsx和pages/user/[username].tsx即可,不需要额外配置next.config.js的重写规则 Link组件直接写公开路径即可:
<Link href={`/@${post.author.username}`}> {post.author.username} </Link>
初始方案部署404原因说明
Next.js的路由优先级在构建阶段就会确定,全捕获路由[...username]的优先级低于普通动态路由[pageSlug],Vercel部署时默认会把未配置getStaticPaths fallback的动态路由直接返回404,就会出现本地开发正常、部署后404的问题。
内容的提问来源于stack exchange,提问作者lumenwrites
相关产品推荐
相关产品推荐

