Next.js 13 Pages结构动态区域前缀路由实现咨询
解决方案:用中间件+动态路由实现动态区域前缀,无需重构到兜底路由
你不需要强制用[[...slug]]这种复杂的兜底路由,通过Next.js的**中间件(Middleware)**结合现有动态路由结构就能实现需求,既不用重复页面,也支持动态获取的区域数据。
核心思路
- 保留现有
/[region]/[brand]/[location].js的动态路由结构 - 用中间件拦截所有请求:
- 识别路径中是否包含有效区域前缀(从Strapi获取的区域列表验证)
- 无前缀时,自动重写为默认区域的路径(比如把
/apple/shanghai重写到/default-region/apple/shanghai) - 若路径中的前缀不是有效区域,重定向到默认区域的对应页面或返回404
具体实现步骤
1. 编写中间件(middleware.js)
import { NextResponse } from 'next/server'; // 缓存Strapi获取的有效区域列表,避免每次请求都调用API let validRegions = []; async function fetchValidRegions() { if (validRegions.length) return validRegions; const res = await fetch('你的Strapi区域列表API地址'); validRegions = await res.json(); return validRegions; } export async function middleware(request) { const { pathname } = request.nextUrl; const validRegions = await fetchValidRegions(); const defaultRegion = '你的默认区域值'; // 比如'cn' // 检查路径是否以有效区域开头 const regionMatch = pathname.match(/^\/([^/]+)/); const hasValidRegionPrefix = regionMatch && validRegions.includes(regionMatch[1]); if (hasValidRegionPrefix) { // 路径包含有效区域,直接放行 return NextResponse.next(); } else if (pathname === '/') { // 根路径重定向到默认区域首页 return NextResponse.redirect(new URL(`/${defaultRegion}`, request.url)); } else { // 无有效区域前缀,重写路径到默认区域 const newPathname = `/${defaultRegion}${pathname}`; const newUrl = new URL(newPathname, request.url); return NextResponse.rewrite(newUrl); } } // 指定中间件生效的路径(排除静态资源和API) export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], };
2. 页面组件中处理区域参数
在/[region]/[brand]/[location].js中,直接获取region参数即可,中间件已经确保这个参数要么是用户传入的有效区域,要么是默认区域:
export async function getServerSideProps(context) { const { region, brand, location } = context.params; // 用region参数请求Strapi对应区域的数据 const data = await fetch(`你的Strapi数据API?region=${region}&brand=${brand}&location=${location}`); const result = await data.json(); return { props: { result, region } }; } export default function LocationPage({ result, region }) { return ( <div> <h1>区域:{region}</h1> <p>品牌:{result.brand}</p> <p>地点:{result.location}</p> </div> ); }
额外优化点
- 给中间件的区域列表加缓存过期策略,避免Strapi区域更新后中间件还在用旧数据
- 页面中添加区域选择器时,直接跳转到对应区域前缀的路径即可完成切换
- 中间件的
rewrite操作不会改变浏览器地址栏,刚好实现类似苹果官网的体验(访问/store时实际用默认区域,但URL保持不变)
内容的提问来源于stack exchange,提问作者devools
相关产品推荐
相关产品推荐

