Vercel 部署 Nuxt 完整教學|2025 Nuxt 3 SSR 上線指南

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

  1. 前往 vercel.com
  2. 點擊 Add NewProject
  3. 選擇 Repository
  4. 點擊 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 設定

  1. 專案 Settings → Environment Variables
  2. 新增變數:
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

可能原因:

  1. 檔案位置錯誤
  2. 檔案名稱錯誤

正確位置:

server/
└── api/
    └── hello.ts  ← 正確

問題三:環境變數讀不到

檢查項目:

  1. 是否使用 useRuntimeConfig()
  2. 公開變數是否在 public
  3. Vercel 是否有設定

偵錯:

// server/api/debug.ts
export default defineEventHandler(() => {
  const config = useRuntimeConfig();
  return {
    public: config.public,
    // 不要在正式環境回傳私密變數
  };
});

問題四:SSR 水合錯誤

錯誤訊息:

Hydration mismatch

常見原因:

  1. 使用了 Date.now() 等時間相關函數
  2. 使用了 Math.random()
  3. 在 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

解決方法:

  1. 優化 API 邏輯
  2. 使用 Edge Runtime
  3. 實作快取
// 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:如何設定自訂網域?

  1. Settings → Domains
  2. 新增網域
  3. 設定 DNS

Q5:免費方案夠用嗎?

對個人專案和小型網站夠用:

  • SSR Functions 有執行時間限制
  • 可能需要監控用量

Vercel 部署失敗?

Build Error、環境變數、自訂網域,我們幫你快速排除問題。

解決 Vercel 問題


延伸閱讀

分享文章:
V

VibeFix

專門解決 AI Vibe Coding 後的疑難雜症,讓你的專案順利上線。

這篇文章有幫到你嗎?

如果還有問題,讓我們直接幫你解決!

聯繫我們