Vercel 404 Not Found 完整解決方案|部署後頁面找不到怎麼辦
部署成功了,但開網頁卻顯示 404?
這是 Vercel 新手最常遇到的問題之一。
Build 沒報錯,部署也成功,但頁面就是找不到。
別擔心,這篇文章整理了所有可能的原因和解法。
一個一個試,總會找到問題在哪。
為什麼部署後會出現 404?
先搞懂 404 是什麼意思。
404 Not Found 代表:伺服器找不到你要的頁面。
在 Vercel 的情況下,通常是這幾種原因:
| 原因 | 發生機率 | 難度 |
|---|---|---|
| SPA 路由設定問題 | ⭐⭐⭐⭐⭐ | 中 |
| Output Directory 錯誤 | ⭐⭐⭐⭐ | 低 |
| 檔案名稱大小寫問題 | ⭐⭐⭐ | 低 |
| Build 失敗但沒注意 | ⭐⭐ | 低 |
| 動態路由設定不當 | ⭐⭐ | 高 |
接下來一個一個看怎麼解決。
原因一:SPA 路由設定問題
這是最常見的原因。
什麼是 SPA 路由問題?
SPA(Single Page Application)的路由是由前端 JavaScript 處理的。
像 React Router、Vue Router 都是前端路由。
問題在哪?
當用戶直接訪問 https://yoursite.com/about:
- 瀏覽器向 Vercel 請求
/about這個檔案 - Vercel 找不到
about.html這個檔案 - 回傳 404
但如果用戶從首頁點連結到 /about,就不會有問題,因為前端路由接管了。
解決方法:設定 rewrites
在專案根目錄建立 vercel.json:
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
這段設定的意思是:
所有找不到的路徑,都導向 index.html,讓前端路由來處理。
不同框架的設定
React(Create React App / Vite):
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
Vue(Vite):
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
Next.js:
Next.js 不需要這個設定,Vercel 會自動處理。
如果還是 404,通常是其他問題。
Nuxt:
Nuxt 也會自動處理,但如果是 SPA 模式,可能需要設定。
設定後還是 404?
確認這些事情:
vercel.json放在專案根目錄(和package.json同層)- 設定後要重新部署才會生效
- 確認
destination的路徑正確
原因二:Output Directory 設定錯誤
Build 輸出的目錄和 Vercel 設定不一致。
檢查方法
- 在 Vercel Dashboard 進入你的專案
- 點擊 Settings → General
- 找到「Build & Development Settings」
- 檢查「Output Directory」設定
常見的 Output Directory
| 框架/工具 | 預設 Output Directory |
|---|---|
| Next.js | .next(自動偵測) |
| Create React App | build |
| Vite | dist |
| Vue CLI | dist |
| Nuxt | .nuxt 或 .output |
| Astro | dist |
| Gatsby | public |
解決方法
方法一:在 Vercel Dashboard 修改
- Settings → General → Build & Development Settings
- 修改 Output Directory 為正確的值
- 重新部署
方法二:在 vercel.json 指定
{
"buildCommand": "npm run build",
"outputDirectory": "dist"
}
怎麼知道正確的 Output Directory?
在本機執行 npm run build,看 build 完成後產生什麼資料夾。
npm run build
ls -la
# 看看產生了什麼資料夾
原因三:檔案名稱大小寫問題
這個問題很陰險。
為什麼會發生?
Windows 和 macOS 的檔案系統對大小寫不敏感:
About.js和about.js被視為同一個檔案
但 Linux(Vercel 的執行環境)對大小寫敏感:
About.js和about.js是兩個不同的檔案
常見錯誤
// 檔案名稱是 About.js
// 但 import 寫成小寫
import About from './about.js'; // ❌ 本機可以,Vercel 找不到
import About from './About.js'; // ✅ 正確
檢查方法
- 看 Vercel 的 Build Log
- 找類似
Module not found或Cannot resolve的錯誤 - 檢查相關檔案的大小寫
解決方法
- 確保 import 路徑和實際檔案名稱大小寫一致
- 用 ESLint 的
import/no-unresolved規則檢查 - 在 Git 中修正檔案名稱:
# Git 預設對大小寫不敏感,要用這個方式改名
git mv About.js about.tmp.js
git mv about.tmp.js about.js
git commit -m "Fix filename case"
大小寫問題很難自己找?可以聯繫我們讓工程師幫你檢查。
原因四:Build 失敗但未注意
有時候 Build 失敗了,但你沒注意到。
可能的情況
- Build 成功但有 Warning,導致某些頁面沒產生
- Build 過程中跳過了某些檔案
- TypeScript 型別錯誤導致某些頁面沒編譯
檢查方法
- 進入 Vercel Dashboard → Deployments
- 點擊最新的 Deployment
- 展開 Build Logs
- 仔細看是否有任何警告或錯誤
常見的隱藏問題
TypeScript 錯誤:
Type error: Property 'xxx' does not exist on type 'yyy'
有些設定會讓 TypeScript 錯誤只是警告,不會阻止 Build,但頁面可能不完整。
動態 import 失敗:
Error: Cannot find module './components/About'
解決方法:
- 修復所有警告和錯誤
- 在本機用
npm run build測試 - 確認 build 完成後所有檔案都存在
原因五:動態路由設定不當
Next.js 的動態路由最容易出問題。
常見問題
1. 動態路由沒有 generateStaticParams
// app/blog/[slug]/page.tsx
// ❌ 如果沒有這個,靜態輸出時會 404
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
2. 使用 output: 'export' 但有動態路由
Next.js 靜態輸出不支援完全動態的路由。
解決方法:
- 使用 generateStaticParams 預先產生所有頁面
- 或不使用靜態輸出
3. Catch-all 路由設定錯誤
// 正確的 catch-all 路由
app/blog/[...slug]/page.tsx
// 錯誤:多餘的括號或格式
app/blog/[[...slug]]/page.tsx // 這是 optional catch-all,行為不同
解決方法
- 確認動態路由有正確的
generateStaticParams - 檢查路由命名格式
- 參考 Next.js 官方文件
快速診斷流程圖
不知道從哪開始?照這個流程檢查:
開始
│
▼
Build 成功嗎? ──否──▶ 看 Build Log 找錯誤
│
是
│
▼
首頁可以開嗎? ──否──▶ 檢查 Output Directory
│
是
│
▼
子頁面 404?
│
是
│
▼
是 SPA 嗎? ──是──▶ 設定 rewrites
│
否
│
▼
是 Next.js 動態路由? ──是──▶ 檢查 generateStaticParams
│
否
│
▼
檢查檔案名稱大小寫
vercel.json 完整設定範例
這是一個常用的 vercel.json 設定:
{
"version": 2,
"buildCommand": "npm run build",
"outputDirectory": "dist",
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
],
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
}
]
}
]
}
針對不同框架的設定
React(Vite):
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
Vue(Vite):
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
Next.js(通常不需要):
{
"trailingSlash": false
}
Nuxt(SPA 模式):
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
常見問題 FAQ
Q1:設定了 rewrites 還是 404?
檢查這些:
vercel.json是否在專案根目錄- 設定後有沒有重新部署
destination路徑是否正確(有些專案是/200.html)
Q2:本機沒問題,部署就 404?
99% 是以下原因:
- 檔案名稱大小寫問題
- 環境變數沒設定
- 路由設定問題
Q3:只有特定頁面 404?
檢查:
- 該頁面的檔案是否存在
- 動態路由是否有
generateStaticParams - 該頁面是否有編譯錯誤
Q4:API 路由 404?
確認:
- API 路由放在正確的位置
- Next.js App Router:app/api/xxx/route.ts
- Next.js Pages Router:pages/api/xxx.ts - 檔案名稱正確
- export 的函數名稱正確(
GET,POST等)
Q5:refresh 頁面就 404?
這是典型的 SPA 路由問題,需要設定 rewrites。
還是無法解決?
如果你試過以上所有方法還是 404:
1. 提供資訊給我們
- Build Log 截圖
- vercel.json 內容
- 專案框架和版本
- 哪些頁面 404
2. 讓專業的來
有些問題需要經驗才能快速定位。
Vercel 部署失敗?
Build Error、環境變數、自訂網域,我們幫你快速排除問題。