如何配置NextJS Middleware匹配[category_code]动态路由?
Next.js Pages路由中Middleware匹配动态分类路由的正确配置
核心问题原因
在Pages路由体系下,Middleware的路由匹配语法和页面文件命名规则不同:页面文件用[category_code].jsx表示动态路由,但Middleware的匹配规则需要用:category_code这种冒号占位符,而非方括号。你之前尝试的/[category_code]是文件命名语法,不适用于Middleware的匹配规则,这就是配置无效的根本原因。
正确配置方案
方式1:精准匹配+排除静态页面
如果你的分类页面都是一级路径(如/tech、/sports),且存在其他静态一级页面(如/about、/home),可以通过以下代码实现:
import { NextResponse } from 'next/server' // 定义不需要检查的静态一级页面 const excludedPages = ['/about', '/contact', '/home', '/404'] export async function middleware(request) { const pathname = new URL(request.url).pathname // 跳过静态页面、API路由和404页面 if (excludedPages.includes(pathname) || pathname.startsWith('/api/')) { return NextResponse.next() } // 提取分类编码(去掉路径开头的斜杠) const categoryCode = pathname.slice(1) // 替换为你实际的分类存在性检查逻辑(如数据库查询、API调用) const categoryExists = await checkCategoryValidity(categoryCode) if (!categoryExists) { // 重写至404页面,保留原URL并返回404状态码 return NextResponse.rewrite(new URL('/404', request.url), { status: 404 }) } // 分类有效,继续处理请求 return NextResponse.next() } // 示例:模拟分类有效性检查 async function checkCategoryValidity(code) { // 这里替换为你的实际校验逻辑 const validCategories = ['tech', 'sports', 'lifestyle'] return validCategories.includes(code) }
方式2:使用matcher缩小作用范围
如果你想让Middleware仅作用于一级动态路径,可以通过导出config.matcher来限定,但需注意该匹配规则会覆盖所有一级路径,所以仍需在函数内排除静态页面:
import { NextResponse } from 'next/server' const excludedPages = ['/about', '/contact', '/home', '/404'] export const config = { // 匹配所有一级路径 matcher: '/:category_code', } export async function middleware(request) { const pathname = new URL(request.url).pathname if (excludedPages.includes(pathname)) { return NextResponse.next() } const categoryCode = pathname.slice(1) const categoryExists = await checkCategoryValidity(categoryCode) if (!categoryExists) { return NextResponse.rewrite(new URL('/404', request.url), { status: 404 }) } return NextResponse.next() } async function checkCategoryValidity(code) { const validCategories = ['tech', 'sports', 'lifestyle'] return validCategories.includes(code) }
关键注意事项
- 使用
NextResponse.rewrite而非redirect:rewrite会保持原URL地址,同时返回404页面和正确的404状态码,更符合SEO和用户体验;如果使用redirect会改变URL,不太适合404场景。 - 务必排除静态页面和API路由:避免Middleware误拦截不需要检查的请求,导致功能异常。
- 分类检查逻辑要异步安全:如果你的检查逻辑涉及数据库查询或外部API调用,确保使用异步函数并正确处理异常。
内容的提问来源于stack exchange,提问作者Ismail Farooq
相关产品推荐
相关产品推荐

