Next.js App Router:将所有路由重定向至嵌套动态根路由
多店铺电商路由重定向最佳实现方案(Next.js App Router)
核心方案:使用 Middleware
这是适配你场景的最优解——Middleware能在请求到达页面之前全局拦截所有路由请求,动态处理Cookie判断和重定向逻辑,既高效又无需在每个页面重复写代码,完美覆盖所有路由重定向需求。
具体实现步骤
1. 创建 Middleware 文件
在项目根目录新建 middleware.ts(或 .js),Next.js 会自动识别并启用这个文件的全局拦截逻辑。
2. 编写 Middleware 核心逻辑
import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { // 排除无需重定向的路径:店铺选择页、静态资源、API路由等 const excludedPaths = ['/select-store', '/_next', '/api', '/favicon.ico'] if (excludedPaths.some(path => request.nextUrl.pathname.startsWith(path))) { return NextResponse.next() } // 从Cookie读取已选店铺ID和购物模式 const storeId = request.cookies.get('storeId')?.value const shoppingMode = request.cookies.get('shoppingMode')?.value // 情况1:已保存店铺和模式信息 if (storeId && shoppingMode) { const targetPath = `/store/${storeId}/sm/${shoppingMode}${request.nextUrl.pathname}` // 避免重复重定向(已在嵌套路由内的请求直接放行) if (!request.nextUrl.pathname.startsWith(`/store/${storeId}/sm/${shoppingMode}`)) { return NextResponse.redirect(new URL(targetPath, request.url)) } return NextResponse.next() } // 情况2:未选择店铺,重定向到选择页并携带当前路径作为跳转参数 const redirectUrl = new URL('/select-store', request.url) redirectUrl.searchParams.set('redirect', encodeURIComponent(request.nextUrl.pathname)) return NextResponse.redirect(redirectUrl) } // 指定Middleware生效的路由范围(匹配所有路由) export const config = { matcher: '/:path*', }
3. 实现店铺选择页面
创建 app/select-store/page.tsx,处理用户选择逻辑,设置Cookie后跳转到目标路由:
'use client' import { useRouter, useSearchParams } from 'next/navigation' import { useState } from 'react' export default function SelectStorePage() { const router = useRouter() const searchParams = useSearchParams() const redirectPath = searchParams.get('redirect') || '/' const [storeId, setStoreId] = useState('') const [shoppingMode, setShoppingMode] = useState('pickup') const handleSubmit = (e: React.FormEvent) => { e.preventDefault() if (!storeId) return // 设置Cookie(有效期可按需调整) document.cookie = `storeId=${storeId}; path=/; max-age=86400` document.cookie = `shoppingMode=${shoppingMode}; path=/; max-age=86400` // 跳转到目标路由 router.push(`/store/${storeId}/sm/${shoppingMode}${redirectPath}`) } return ( <div> <h2>选择店铺和购物模式</h2> <form onSubmit={handleSubmit}> <div> <label>店铺ID:</label> <input type="text" value={storeId} onChange={(e) => setStoreId(e.target.value)} required /> </div> <div> <label>购物模式:</label> <select value={shoppingMode} onChange={(e) => setShoppingMode(e.target.value)} > <option value="pickup">自提</option> <option value="delivery">配送</option> </select> </div> <button type="submit">确认选择</button> </form> </div> ) }
其他方案的局限性
- 配置文件重定向:
next.config.js里的重定向只能是静态规则,无法动态读取用户Cookie中的店铺ID和模式,完全不适用你的动态场景。 - 页面内重定向:需要在每个页面组件中写重定向逻辑,代码冗余,且会出现页面闪烁(页面开始渲染后才触发重定向),用户体验差。
内容的提问来源于stack exchange,提问作者makezi
相关产品推荐
相关产品推荐

