You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vercel托管的Next.js应用如何免重部署通过API配置维护页面

Vercel托管Next.js动态维护页实现方案(无需重部署)

维护页参考效果

核心实现思路

完全基于Next.js原生能力适配Vercel边缘运行时,不需要修改环境变量、不需要重新部署,通过接口返回的siteStatus字段实时控制页面展示:

  • 所有用户请求优先经过运行在Vercel边缘节点的Next.js Middleware,无冷启动延迟
  • 中间件层拉取状态接口的siteStatus值,配置短周期边缘缓存,避免每次请求都打状态接口
  • 状态为down时直接将请求重写到内置维护页,返回503服务不可用状态码,对SEO友好
  • 状态为up时直接放行到正常业务路由
  • 切换状态仅需修改状态接口返回值,最长缓存过期时间(建议10-30秒)后全Vercel节点自动生效

落地步骤

1. 编写核心中间件

在项目根目录(或src目录)创建middleware.ts文件:

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

// 路径白名单:维护页路由、静态资源、接口路径直接放行,避免循环重写
const WHITELIST_PATHS = ['/maintenance', '/_next/static/', '/favicon.ico', '/api/']
// 状态缓存时长,单位秒,10-30秒区间兼顾生效速度与接口压力
const STATUS_CACHE_TTL = 15

export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl

  // 白名单路径直接放行
  if (WHITELIST_PATHS.some(path => pathname.startsWith(path))) {
    return NextResponse.next()
  }

  // 拉取站点状态,Vercel边缘自动按TTL缓存结果,不会重复请求源接口
  const statusResp = await fetch('替换为你自己的状态接口地址', {
    next: { revalidate: STATUS_CACHE_TTL }
  })
  const { siteStatus } = await statusResp.json()

  // 站点正常运行时的处理
  if (siteStatus === 'up') {
    // 若用户手动访问维护页路径,重定向到首页
    if (pathname === '/maintenance') {
      return NextResponse.redirect(new URL('/', request.url))
    }
    return NextResponse.next()
  }

  // 站点维护状态时的处理
  if (siteStatus === 'down') {
    // 重写到维护页,地址栏URL保持用户原访问路径,体验更友好
    const rewriteUrl = request.nextUrl.clone()
    rewriteUrl.pathname = '/maintenance'
    const response = NextResponse.rewrite(rewriteUrl)
    // 返回503状态码告知搜索引擎为临时停机,避免索引被清除
    response.status = 503
    // 设置重试头,告知爬虫间隔多久后重新访问
    response.headers.set('Retry-After', String(STATUS_CACHE_TTL * 4))
    return response
  }

  return NextResponse.next()
}

// 配置中间件匹配站点所有请求路径
export const config = {
  matcher: '/:path*',
}

2. 开发维护页面

根据参考的设计稿,在对应路由下编写维护页即可:

  • App Router项目创建app/maintenance/page.tsx
  • Pages Router项目创建pages/maintenance.tsx
    页面样式建议优先用内联样式或全局静态样式,静态资源路径已经在中间件白名单内,不会出现加载失败问题。

3. 状态接口选型建议

状态接口优先选择高可用的边缘存储服务,避免接口故障导致站点访问异常:

  • 可直接使用Vercel KV存储siteStatus值,写一个简单的Serverless接口读取KV值,切换状态时调用接口修改KV值即可
  • 也可使用Upstash Redis、Cloudflare KV等同类边缘存储服务,延迟极低、可用性有保障

方案特性

  • 零部署成本:切换维护状态不需要修改项目代码、不需要调整环境变量、不需要触发Vercel重新部署,最长30秒内全节点生效
  • 性能损耗可忽略:中间件运行在Vercel边缘节点,加上短周期缓存,用户请求几乎感知不到额外延迟
  • SEO友好:维护状态自动返回标准503状态码与Retry-After头,不会损伤站点搜索权重
  • 扩展灵活:可直接在中间件中增加管理员IP白名单、特定Cookie绕过等逻辑,满足个性化需求
  • 全版本兼容:同时支持Next.js App Router与Pages Router架构,不需要改造现有业务代码

注意事项

  • 不要把状态缓存时间设置过长,否则状态切换生效太慢;也不要设置过短,否则会对状态接口造成不必要的压力,10-30秒为最优区间
  • 新增静态资源路径、第三方埋点接口路径时记得同步加入中间件白名单,避免维护模式下资源加载失败
  • 状态接口要配置跨域允许,避免边缘节点拉取时被跨域策略拦截

内容的提问来源于stack exchange,提问作者Loreen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:36:25