mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
3098 字
8 分钟
部署到 Vercel 后 API 一直 404?Vercel 平台框架检测问题
2026-03-21

问题背景#

换了 Next.js 框架后,代码部署到 Vercel:

  • 代码放在 pages/api/like.ts
  • 访问 https://xxx.com/api/like
  • 结果:Error: Cannot GET /api/like

Vercel 根本没识别出这是一个 Next.js 项目,而是把整个项目当成了静态文件处理。


核心结论#

当 Vercel 检测为 None(框架未知)时,默认会将项目当作”纯静态站点”处理。这意味着所有 API 路由都不会被启用,直接导致 404 错误。

首次部署或项目结构不标准时,Vercel 可能无法自动检测出 Next.js 框架,此时需要手动创建 vercel.json 文件指定 framework'nextjs'


我的真实经历#

项目背景#

试着把项目从 Node.js 迁移到 Next.js,想在 Vercel 上跑起来。

原来 Node.js 的结构:

blog-like-api/
├── api/
│ └── like.ts
├── page/
│ └── index.ts
└── package.json

迁移到 Next.js 后变成了:

blog-like-api/
├── pages/
│ ├── api/
│ │ └── like.ts → /api/like
│ └── index.ts → /
├── package.json
└── ...

但在 Vercel 上跑不通 —— Vercel 检测不出这是 Next.js,所有文件都当静态文件处理,API 路由直接失效。加了 vercel.json 指定框架后问题才解决。

换了 Next.js 后的遭遇#

按照 Next.js 的约定式路由,pages/api/like.ts 应该映射到 /api/like

但 Vercel 返回:

Cannot GET /api/like

Vercel 没有识别出这是 Next.js 项目。

解决方案:指定 framework#

需要创建 vercel.json 强制指定框架:

{
"framework": "nextjs"
}

加上这个配置后,Vercel 才正确识别 Next.js 框架,API 路由才正常工作。


Vercel 的框架检测机制#

自动检测原理#

Vercel 部署时会自动检测项目使用的框架,检测依据包括:

检测依据说明
package.jsondependencies检测是否安装了特定框架的包
特定文件夹结构pages/app/src/
配置文件next.config.jsnuxt.config.ts
构建脚本"build": "next build"

检测失败的后果#

当 Vercel 检测为 None(框架未知)时:

Vercel 会默认将项目当作”纯静态站点”处理。此时 Next.js 的 API 路由功能不会被启用,所有 pages/api/*app/api/* 的文件都不会被当作 API 端点。

具体来说:

  • pages/api/like.ts 这类 API 文件,在部署后不会被编译成 Serverless Function
  • 相反,它们会被当作普通的静态资源文件处理
  • 访问 /api/like 时,Vercel 找不到对应的端点,返回 404 或 Cannot GET 错误

这就是为什么即使你正确放置了 pages/api/like.ts,访问 /api/like 依然会返回 404。

可能误判的原因#

原因说明
混合多种框架package.json 同时有 React 和 Vue 依赖,Vercel 无法判断主框架
自定义结构没有使用框架的默认文件夹结构
缺少关键依赖依赖在 devDependencies 而非 dependencies
首次部署检测失败Vercel 首次部署时的误判
没有配置文件缺少 next.config.js 等框架配置

误判案例:混合框架依赖#

假设 package.json 是这样:

{
"dependencies": {
"react": "^18.0.0",
"vue": "^3.0.0",
"next": "^14.0.0"
}
}

这种情况下,Vercel 可能无法判断主框架是哪个。虽然项目实际用的是 Next.js(React 生态),但同时存在 Vue 依赖会增加检测的不确定性。

何时需要 vercel.json,何时可以依赖自动检测#

情况推荐
结构标准的 Next.js 项目(包含 next.config.jspages/ 等)通常能自动检测,无需 vercel.json
从其他框架迁移的项目建议添加 vercel.json
项目结构特殊或使用自定义文件夹建议添加 vercel.json
首次部署失败必须添加 vercel.json

如何确认是否检测正确#

查看 Vercel 构建日志。在 Vercel 控制台:

  1. 进入 Deployments 页面
  2. 选择对应的部署
  3. 点击对应的部署进入详情页
  4. Logs 标签下查看构建日志

日志中会显示框架检测结果:

[INFO] Detected Framework: Next.js ← 正确识别
[INFO] Detected Framework: None ← 检测失败,需要手动指定

强制指定框架#

vercel.json 配置#

创建 vercel.json 文件明确指定框架:

{
"framework": "nextjs"
}

支持的框架值#

framework 值框架触发效果
"nextjs"Next.js启用 Next.js 构建流程和 API 路由
"nuxtjs"Nuxt.js启用 Nuxt 构建流程和 API 路由
"react"Create React App启用 React 构建流程
"vue"Vue启用 Vue 构建流程
"svelte"Svelte启用 Svelte 构建流程
"angular"Angular启用 Angular 构建流程
"static"纯静态站点彻底禁用所有 API 路由,所有文件当静态资源处理
"nodejs"Node.js 原生项目启用 Node.js 构建流程

重要:选择正确的 framework 值至关重要。不同的框架值会触发 Vercel 完全不同的构建流程和路由规则

错误选择的风险:如果错误地将 "framework" 设置为 "static",即使你的文件结构完全正确,Next.js 的 API 路由也会被彻底禁用。这是因为 "static" 会告诉 Vercel 这是一个纯静态站点,不会启动任何 API 路由编译流程。

这些值是 Vercel 官方文档中定义的标准标识符,具体支持情况请以 Vercel 官方文档 为准。

vercel.json 完整配置示例#

{
"framework": "nextjs",
"buildCommand": "npm run build",
"devCommand": "npm run dev",
"installCommand": "npm install"
}

常见错误与解决方案#

错误一:Vercel 没识别出框架#

❌ Cannot GET /api/like
✅ 添加 vercel.json 指定 framework

解决

{
"framework": "nextjs"
}

错误二:Pages 和 App 路由混用#

❌ pages/api/like/route.ts(不存在的结构)
✅ pages/api/like.ts(Pages 路由)
✅ app/api/like/route.ts(App 路由)

错误三:以为是 Express 的自定义路由#

常见认知误区:许多从 Express 转来的开发者,习惯了代码定义路由,容易误以为 Next.js 也可以通过配置自定义路由路径。

实际上,Next.js 的约定式路由是固定的、不可自定义的。你不能把 pages/api/like.ts 映射到 /custom/like,也不能把 app/api/users.ts 映射到 /api/v1/users

如果你习惯了 Express 中 app.get('/path', handler) 的写法,你可能会误以为 Next.js 也能自定义路径——但这是不成立的

❌ 期望 pages/api/like.ts 映射到 /custom/like
✅ Next.js 不能自定义路由路径

错误四:buildCommand 不正确#

{
"framework": "nextjs",
"buildCommand": "npm run build",
"devCommand": "npm run dev",
"installCommand": "npm install"
}

Next.js 的约定式路由#

前提:只有当 Vercel 正确识别 Next.js 框架后,才会应用下面的约定式路由规则。如果框架检测失败,无论文件放在 pages/api 还是 app/api,都不会被识别为 API 路由。

Pages 路由(pages/ 目录)#

这是 Next.js 传统的路由方式:

文件系统 → URL 路径
pages/
├── index.ts → /
├── about.ts → /about
├── contact.ts → /contact
├── api/
│ ├── like.ts → /api/like
│ ├── users.ts → /api/users
│ └── users/
│ └── index.ts → /api/users
└── posts/
├── index.ts → /posts
└── [slug].ts → /posts/123(动态路由)

App 路由(app/ 目录,Next.js 13+)#

这是新版路由方式,使用 React Server Components:

文件系统 → URL 路径
app/
├── page.tsx → /
├── about/
│ └── page.tsx → /about
├── contact/
│ └── page.tsx → /contact
├── api/
│ └── like/
│ └── route.ts → /api/like
└── posts/
├── page.tsx → /posts
└── [slug]/
└── page.tsx → /posts/123(动态路由)

注意:App 路由中每个页面文件必须命名为 page.tsx(或 page.js),不能使用 index.tsx。这是 Next.js 官方约定的命名规范。

Pages vs App 路由对比#

特性Pages 路由App 路由
目录pages/app/
API 文件pages/api/*.tsapp/api/*/route.ts
默认导出函数组件函数组件
数据获取getServerSidePropsServer Components 中直接异步获取
布局_app.tsxlayout.tsx
状态管理React 原生状态及第三方库React 原生状态及第三方库(需在客户端组件中使用)

常见错误:文件放错位置#

重要提醒:即使框架检测正确,文件放错位置同样会导致 404。

❌ 将 API 文件放在 public/ 目录下
public/api/like.ts → 不会映射到 /api/like
❌ 将 API 文件放在根目录的任意位置
api/like.ts → 不会映射到 /api/like
✅ Pages 路由:pages/api/*.ts
✅ App 路由:app/api/*/route.ts

Next.js 的约定式路由只认 pages/api/app/api/ 这两个固定目录,其他位置的 API 文件不会被处理。


不同平台的路由映射规则#

对比一览#

平台/框架路由定义方式API 文件位置API URL
Express/Koa代码定义任意(在代码里指定)代码里写 /api 就是 /api
Next.js (Pages)约定式pages/api/*.ts文件路径自动映射
Next.js (App)约定式app/api/*/route.ts文件路径自动映射
Nuxt 3约定式server/api/*.ts文件路径自动映射
Gatsby约定式src/pages/*.js文件路径自动映射
纯静态文件结构public/*与 public 下结构相同

核心洞察:使用约定式路由的框架(如 Next.js)将路由逻辑与文件系统强绑定,而代码定义路由(如 Express)则允许在代码中自由定义路径。理解这一点是避免路径混淆的关键。

核心区别#

代码定义路由(如 Express)给予开发者完全的路径控制权,而约定式路由(如 Next.js)则通过文件系统结构隐式定义路径,牺牲了灵活性以换取开发效率和一致性。

Node.js/Express(代码定义路由)

目录名和路由没有直接关系page/index.js 不等于 / 路由,只是在代码里挂载为 /

blog-like-api/
├── page/
│ └── index.js ← 只是文件名叫 index,不是 /
├── api/
│ └── like.js ← 只是文件名叫 like,不是 /api/like
└── app.js
app.js
const pageIndex = require('./page/index');
const apiLike = require('./api/like');
app.use('/', pageIndex); // page/index.js 里的 get('/') 才映射到 /
app.use('/api', apiLike); // api/like.js 里的 get('/') 才映射到 /api

Next.js(约定式路由)

文件名直接决定 URL,pages/ 是约定俗成的目录名称(不是固定的,你可以用 app/):

pages/
├── index.ts → /
├── about.ts → /about
└── api/
└── like.ts → /api/like

关键差异:Express 里你可以把 page/index.js 挂载到 /helloapi/like.js 挂载到 /world,完全自由。而 Next.js 不行,pages/api/like.ts 只能映射到 /api/like,不能自定义。


调试步骤#

第一步:检查 Vercel 构建日志#

查看是否正确识别了框架。在 Vercel 控制台进入 Deployments → 选择部署 → 在 Logs 标签下查看构建日志:

[INFO] Detected Framework: Next.js ← 正确
[INFO] Detected Framework: None ← 问题在这里

这直接印证了核心结论中的判断:如果检测为 None,说明 Vercel 没有识别出框架,项目被当作纯静态处理。

第二步:添加 vercel.json#

{
"framework": "nextjs"
}

第三步:检查路由文件位置#

路由方式正确位置
Pages 路由pages/api/*.ts
App 路由app/api/*/route.ts

第四步:本地测试#

# 安装 Vercel CLI
npm i -g vercel
# 本地运行
vercel dev
# 通常显示 http://localhost:3000
# 本地运行后:
# pages/api/like.ts → http://localhost:3000/api/like

重要:本地测试无法验证 Vercel 的框架检测机制vercel dev 主要验证路由逻辑和代码正确性,但它无法模拟 Vercel 的自动检测流程。

本地测试的验证范围:

能验证不能验证
API 路由逻辑正确性Vercel 的框架检测机制
函数代码执行正确性Vercel 特定的构建流程
本地开发环境运行边缘函数或 Serverless Functions 的线上行为
环境变量的线上配置

第五步:健康检查接口#

添加健康检查接口,用于验证部署结果:

pages/api/test.ts
export default function handler(req, res) {
res.status(200).json({
message: "API 正常",
url: req.url,
method: req.method,
timestamp: new Date().toISOString()
});
}

用途:在添加 vercel.json 并重新部署后,立即访问 /api/test 验证 API 路由是否已恢复正常。

健康检查接口的多重用途:

  1. 验证部署和路由:确认 API 是否被正确部署和路由
  2. 前端健康探测:作为前端应用检测后端服务状态的探测点
  3. CI/CD 流程集成:在持续集成/部署流程中作为健康检查端点

预防措施#

预防胜于治疗。在初始化 Next.js 项目时,就提前创建 vercel.json 文件,并将其纳入版本控制,可以从根源上避免此类问题。

推荐做法#

  1. 使用 create-next-app 创建项目后,立即添加 vercel.json

    npx create-next-app my-blog --typescript
    cd my-blog
    # 创建 vercel.json
    echo '{"framework": "nextjs"}' > vercel.json
  2. 将其纳入版本控制

    确保团队成员和 CI/CD 环境使用相同的配置:

    git add vercel.json
    git commit -m "chore: add vercel.json with explicit framework"
  3. 在项目文档中记录

    如果项目有 README,建议在其中记录 vercel.json 的作用,避免其他协作者误删。


总结#

核心要点#

  1. 换了框架后,Vercel 可能检测不出来 — 需要 vercel.json 强制指定
  2. 检测为 None 时,项目被当作纯静态处理 — API 文件不会被编译成 Serverless Function
  3. Next.js 用约定式路由 — 文件位置决定 URL,不能自定义
  4. Pages 和 App 路由结构不同 — 不要混用
  5. 本地测试无法验证框架检测 — 必须以 Vercel 构建日志为准

一句话记住#

Vercel 不一定能猜对框架。当出现”Cannot GET”时,先检查 Vercel 有没有正确识别你的框架。

常见问题速查表#

问题现象可能原因解决方案
API 返回 404Vercel 未识别框架添加 vercel.json 指定 "framework": "nextjs"
框架检测为 None项目结构特殊或缺少依赖检查 package.json 依赖和文件夹结构,必要时添加 vercel.json
API 文件位置正确但无效文件放在 public/ 或其他非约定目录确认文件在 pages/api/app/api/ 目录下
框架值设为 static 后 API 全挂误将 framework 设置为 “static”更改为 "framework": "nextjs"

快速修复清单#

问题解决方案
Vercel 没识别框架添加 vercel.json 指定 framework
Pages 路由不工作确认文件在 pages/api/*.ts
App 路由不工作确认文件在 app/api/*/route.ts
本地测试vercel dev

读者行动清单#

  1. 检查项目结构:确认是否使用了标准的 Next.js 项目结构(包含 next.config.jspages/app/

  2. 查看 Vercel 构建日志:确认框架检测结果是否为 None

  3. 如果检测失败:在项目根目录创建 vercel.json,添加 "framework": "nextjs"

  4. 确认 API 文件位置:Pages 路由放在 pages/api/*.ts,App 路由放在 app/api/*/route.ts

  5. 本地测试:使用 vercel dev 验证路由逻辑

  6. 重新部署:触发新的部署流程

    (重要) 添加 vercel.json 后,必须触发一次新的部署(例如 git push),否则配置不会生效。

  7. 验证 API 端点:通过健康检查接口 /api/test 或实际端点 /api/like 确认正常工作

vercel.json 最小配置#

{
"framework": "nextjs"
}

EOF

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

部署到 Vercel 后 API 一直 404?Vercel 平台框架检测问题
https://bayunmoyu.com/posts/vercel-routing/
作者
八云墨玉
发布于
2026-03-21
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00