如何在特定环境下禁用Vercel Middleware且不触发其调用?
解决Vercel生产环境禁用NextJS Middleware的方案
方案一:构建时动态替换Middleware文件(最彻底)
该方法能让生产环境完全加载无逻辑、无路由匹配的Middleware,彻底避免触发调用:
准备两个Middleware文件:
middleware.preview.ts:写入你的IP拦截逻辑(原Middleware代码)middleware.prod.ts:生产环境用的空Middleware,内容如下:export function middleware() { // 生产环境无任何操作 } export const config = { matcher: [], // 匹配空数组,不会触发任何路由 };
修改
package.json的构建脚本,根据Vercel环境变量切换Middleware文件:"scripts": { "build": "if [ \"$VERCEL_ENV\" = \"production\" ]; then cp middleware.prod.ts middleware.ts; else cp middleware.preview.ts middleware.ts; fi && next build" }Vercel会自动设置
VERCEL_ENV变量:预览环境值为preview,生产环境为production,构建时会自动复制对应文件到middleware.ts(NextJS默认加载的Middleware入口)。
方案二:利用环境变量控制Middleware生效范围
如果不想替换文件,可在原Middleware的config.matcher里结合环境变量,通过构建时注入的变量控制匹配范围:
在
next.config.js里配置环境变量注入:module.exports = { env: { IS_PRODUCTION: process.env.VERCEL_ENV === 'production', }, };修改Middleware的配置与逻辑:
import { NextResponse } from 'next/server'; export function middleware(request) { // 仅预览环境执行IP拦截逻辑 if (!process.env.IS_PRODUCTION) { const allowedIps = ['xxx.xxx.xxx.xxx', 'yyy.yyy.yyy.yyy']; const clientIp = request.ip || request.headers.get('x-forwarded-for'); if (!allowedIps.includes(clientIp)) { return new NextResponse('Unauthorized', { status: 403 }); } } return NextResponse.next(); } export const config = { matcher: process.env.IS_PRODUCTION ? [] : ['/:path*'], // 生产环境不匹配任何路由 };此方案通过设置空匹配器,让生产环境下Middleware不会被任何路由触发,比在函数内提前退出更彻底。
注意事项
- Vercel构建环境为Linux系统,方案一的shell命令可直接运行,无需担心跨平台问题。
- 建议将
middleware.ts加入.gitignore,避免本地开发时的文件冲突,仅让构建脚本生成该文件。
内容的提问来源于stack exchange,提问作者Marcel Gruber
相关产品推荐
相关产品推荐

