如何在Next.js中创建适配两类动态URL格式的页面结构?
在Next.js中实现多参数路由匹配与页面跳转
1. 调整页面路由结构
根据需求直接拆分出对应不同参数数量的路由页面即可:
- 处理3个动态参数的页面:创建
/pages/[countryCode]/[category]/[genre]/index.js,负责渲染genre页面内容 - 处理4个动态参数的页面:创建
/pages/[countryCode]/[category]/[genre]/[performer].js,负责渲染performer页面内容
Next.js会自动匹配对应层级的URL:
- 访问
/us/music/rock时,自动命中index.js页面 - 访问
/us/music/rock/metallica时,自动命中[performer].js页面
2. 动态参数校验(确保countryCode符合规则)
要求countryCode必须是两位小写字母,可通过两种方式实现参数校验:
方式一:页面服务端渲染方法中校验
以三层参数的index.js为例:
import { useRouter } from 'next/router'; import { useEffect } from 'react'; export default function GenrePage() { const router = useRouter(); const { countryCode, category, genre } = router.query; // 客户端补充校验(可选,服务端校验更可靠) useEffect(() => { if (countryCode && !/^[a-z]{2}$/.test(countryCode)) { router.push('/404'); } }, [router, countryCode]); return ( <div> <h1>Genre Page</h1> <p>国家代码:{countryCode}</p> <p>分类:{category}</p> <p>流派:{genre}</p> </div> ); } // 服务端校验(推荐) export async function getServerSideProps(context) { const { countryCode } = context.params; if (!/^[a-z]{2}$/.test(countryCode)) { return { notFound: true, // 返回404页面 // 也可改为重定向到首页:redirect: { destination: '/', permanent: false } }; } return { props: { countryCode, category: context.params.category, genre: context.params.genre }, }; }
四层参数的[performer].js可复用相同校验逻辑,仅需额外获取performer参数即可。
方式二:用Middleware统一校验所有路由
若不想在每个页面重复写校验逻辑,可在项目根目录创建middleware.js文件,全局拦截路由并校验:
import { NextResponse } from 'next/server'; export function middleware(request) { const pathParts = request.nextUrl.pathname.split('/').filter(Boolean); // 仅处理3层或4层参数的路由 if (pathParts.length === 3 || pathParts.length === 4) { const countryCode = pathParts[0]; if (!/^[a-z]{2}$/.test(countryCode)) { return NextResponse.rewrite(new URL('/404', request.url)); } } return NextResponse.next(); } // 指定需要拦截的路由规则 export const config = { matcher: ['/([a-z]{2})/:category/:genre', '/([a-z]{2})/:category/:genre/:performer'], };
3. 主动路由跳转(可选)
若需在页面内主动跳转(比如从genre页面跳转到performer页面),可使用Next.js的useRouter钩子:
import { useRouter } from 'next/router'; function GenrePage() { const router = useRouter(); const goToPerformer = () => { router.push(`/${router.query.countryCode}/${router.query.category}/${router.query.genre}/metallica`); }; return <button onClick={goToPerformer}>查看Metallica页面</button>; }
内容的提问来源于stack exchange,提问作者Ajith Arasu
相关产品推荐
相关产品推荐

