Vercel 部署 Nuxt 完整教學|2025 Nuxt 3 SSR 上線指南
Nuxt 是 Vue 的全端框架。
它支援 SSR(伺服器端渲染)和 SSG(靜態生成)。
部署到 Vercel,可以充分發揮 Nuxt 的潛力。
這篇文章教你如何把 Nuxt 應用部署到 Vercel。
Nuxt + Vercel 的優勢
完美整合
| 功能 | 支援程度 |
|---|---|
| SSR(伺服器端渲染) | 完整支援 |
| SSG(靜態生成) | 完整支援 |
| ISR(增量靜態再生) | 完整支援 |
| API Routes | 完整支援 |
| Edge Rendering | 支援 |
Vercel 自動優化
- 自動偵測 Nuxt 專案
- 自動設定 Serverless Functions
- 自動啟用 Edge Network
- 自動處理路由
專案準備
Nuxt 3 專案結構
my-nuxt-app/
├── .nuxt/
├── public/
├── server/
│ └── api/
│ └── hello.ts
├── pages/
│ ├── index.vue
│ └── about.vue
├── components/
├── composables/
├── nuxt.config.ts
├── package.json
└── tsconfig.json
package.json
{
"name": "my-nuxt-app",
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"generate": "nuxt generate",
"preview": "nuxt preview"
},
"dependencies": {
"nuxt": "^3.11.0"
}
}
本機測試
# SSR 模式
npm run build
npm run preview
# SSG 模式
npm run generate
npx serve .output/public
渲染模式選擇
SSR(伺服器端渲染)
適合: 動態內容、需要 SEO、即時資料
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true, // 預設就是 true
});
部署指令: npm run build
SSG(靜態生成)
適合: 內容網站、部落格、文件
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true,
nitro: {
prerender: {
routes: ['/'],
crawlLinks: true,
},
},
});
部署指令: npm run generate
Hybrid(混合模式)
適合: 部分頁面靜態、部分頁面動態
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // 靜態生成
'/blog/**': { isr: 3600 }, // ISR,1 小時重新驗證
'/api/**': { cors: true }, // API 路由
'/admin/**': { ssr: false }, // 客戶端渲染
},
});
部署到 Vercel
方法一:從 GitHub 部署
步驟一:推送到 GitHub
git init
git add .
git commit -m "Initial commit"
gh repo create my-nuxt-app --public --source=. --push
步驟二:連接 Vercel
- 前往 vercel.com
- 點擊 Add New → Project
- 選擇 Repository
- 點擊 Import
步驟三:確認設定
Vercel 自動偵測 Nuxt:
| 設定項目 | 值 |
|---|---|
| Framework | Nuxt.js |
| Build Command | npm run build |
| Output Directory | .output |
步驟四:部署
點擊 Deploy。
方法二:Vercel CLI
npm install -g vercel
vercel login
vercel
環境變數設定
Nuxt 環境變數
公開變數(會暴露給前端):
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// 私密變數(只在伺服器端)
apiSecret: process.env.API_SECRET,
// 公開變數(前後端都可用)
public: {
apiBase: process.env.NUXT_PUBLIC_API_BASE,
},
},
});
使用方式:
<script setup>
const config = useRuntimeConfig();
// 前端可用
console.log(config.public.apiBase);
// 只在伺服器端可用
// console.log(config.apiSecret); // 前端會是 undefined
</script>
在 Vercel 設定
- 專案 Settings → Environment Variables
- 新增變數:
Name: NUXT_PUBLIC_API_BASE
Value: https://api.example.com
Name: API_SECRET
Value: your-secret-key
.env 檔案
# .env
NUXT_PUBLIC_API_BASE=https://api.example.com
API_SECRET=your-secret-key
注意: .env 不要推到 Git。
API Routes
建立 API 端點
// server/api/hello.ts
export default defineEventHandler((event) => {
return {
message: 'Hello from Nuxt API!',
};
});
訪問: https://your-app.vercel.app/api/hello
動態路由
// server/api/users/[id].ts
export default defineEventHandler((event) => {
const id = event.context.params?.id;
return {
userId: id,
name: `User ${id}`,
};
});
POST 請求
// server/api/contact.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event);
// 處理表單...
return {
success: true,
message: '訊息已收到',
};
});
使用環境變數
// server/api/data.ts
export default defineEventHandler((event) => {
const config = useRuntimeConfig();
// 可以使用私密變數
const secret = config.apiSecret;
return {
data: 'protected data',
};
});
ISR 設定
什麼是 ISR?
ISR(Incremental Static Regeneration)結合了 SSG 和 SSR:
- 首次訪問時靜態生成
- 設定時間後重新驗證
- 背景更新,使用者看到快取版本
設定 ISR
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/blog/**': {
isr: 3600, // 1 小時重新驗證
},
'/products/**': {
isr: 60, // 1 分鐘重新驗證
},
},
});
頁面層級設定
<!-- pages/blog/[slug].vue -->
<script setup>
defineRouteRules({
isr: 3600,
});
</script>
效能優化
啟用壓縮
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
compressPublicAssets: true,
},
});
圖片優化
使用 Nuxt Image:
npm install @nuxt/image
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/image'],
image: {
provider: 'vercel',
},
});
<template>
<NuxtImg
src="/photo.jpg"
width="400"
height="300"
format="webp"
loading="lazy"
/>
</template>
快取設定
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/api/**': {
cache: {
maxAge: 60,
},
},
'/static/**': {
headers: {
'Cache-Control': 'public, max-age=31536000, immutable',
},
},
},
});
減少 Bundle 大小
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
payloadExtraction: true,
},
build: {
analyze: true, // 分析 bundle
},
});
Edge Rendering
啟用 Edge Runtime
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'vercel-edge',
},
});
特定路由使用 Edge
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/api/fast': {
edge: true,
},
},
});
Edge 限制
- 不支援完整 Node.js API
- 記憶體限制(128 MB)
- 執行時間限制(30 秒)
常見問題排解
問題一:Build 失敗
錯誤訊息:
Error: Cannot find module 'nitropack'
解決方法:
# 清除快取重新安裝
rm -rf node_modules .nuxt .output
npm install
npm run build
問題二:API 路由 404
可能原因:
- 檔案位置錯誤
- 檔案名稱錯誤
正確位置:
server/
└── api/
└── hello.ts ← 正確
問題三:環境變數讀不到
檢查項目:
- 是否使用
useRuntimeConfig() - 公開變數是否在
public下 - Vercel 是否有設定
偵錯:
// server/api/debug.ts
export default defineEventHandler(() => {
const config = useRuntimeConfig();
return {
public: config.public,
// 不要在正式環境回傳私密變數
};
});
問題四:SSR 水合錯誤
錯誤訊息:
Hydration mismatch
常見原因:
- 使用了
Date.now()等時間相關函數 - 使用了
Math.random() - 在 setup 中直接存取
window
解決方法:
<script setup>
// ❌ 會造成水合錯誤
const time = Date.now();
// ✅ 使用 ref,在 mounted 後設定
const time = ref(null);
onMounted(() => {
time.value = Date.now();
});
</script>
問題五:Serverless Function 超時
錯誤訊息:
504 Gateway Timeout
解決方法:
- 優化 API 邏輯
- 使用 Edge Runtime
- 實作快取
// server/api/data.ts
export default defineEventHandler(async (event) => {
// 設定快取
setResponseHeader(event, 'Cache-Control', 's-maxage=60');
// 快速回應
return { data: 'cached data' };
});
Nuxt Content 整合
安裝 Nuxt Content
npm install @nuxt/content
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content'],
});
使用 Markdown
content/
└── blog/
└── first-post.md
---
title: 我的第一篇文章
date: 2025-01-15
---
# 我的第一篇文章
這是內容...
顯示內容
<!-- pages/blog/[...slug].vue -->
<template>
<ContentDoc />
</template>
在 Vercel 部署
Nuxt Content 會在 build 時生成,完全支援 Vercel。
部署檢查清單
部署前
- [ ]
npm run build成功 - [ ] 本機預覽正常
- [ ] 環境變數已在 Vercel 設定
- [ ] API Routes 測試正常
- [ ] 渲染模式選擇正確
部署後
- [ ] 頁面正常顯示
- [ ] SSR/SSG 正確運作
- [ ] API 端點可訪問
- [ ] 環境變數正確
- [ ] SEO meta 正確
常見問題 FAQ
Q1:Nuxt 2 還能部署嗎?
可以,但建議升級到 Nuxt 3:
- 更好的效能
- 更好的 TypeScript 支援
- 更多功能
Q2:SSR 和 SSG 怎麼選?
| 選擇 SSR | 選擇 SSG |
|---|---|
| 動態內容 | 靜態內容 |
| 即時資料 | 不常更新 |
| 個人化內容 | 公開內容 |
不確定就用 Hybrid 模式。
Q3:Vercel 會自動處理 Nuxt 嗎?
會,Vercel 有專門的 Nuxt 支援:
- 自動偵測框架
- 自動設定 Serverless Functions
- 自動啟用 ISR
Q4:如何設定自訂網域?
- Settings → Domains
- 新增網域
- 設定 DNS
Q5:免費方案夠用嗎?
對個人專案和小型網站夠用:
- SSR Functions 有執行時間限制
- 可能需要監控用量
Vercel 部署失敗?
Build Error、環境變數、自訂網域,我們幫你快速排除問題。