Vercel 環境變數設定完整教學|2025 最佳實踐指南

Vercel 環境變數設定完整教學|2025 最佳實踐指南

環境變數沒設好,部署就會出問題。

API Key 抓不到、資料庫連不上...

這篇文章教你如何正確設定 Vercel 環境變數。


什麼是環境變數?

環境變數是儲存在執行環境中的設定值。

為什麼需要環境變數?

  1. 安全性: API Key、密碼不放在程式碼中
  2. 彈性: 不同環境使用不同設定
  3. 方便: 不用改程式碼就能改設定

常見的環境變數

# API Keys
OPENAI_API_KEY=sk-xxxx
STRIPE_SECRET_KEY=sk_live_xxxx

# 資料庫
DATABASE_URL=postgresql://user:pass@host:5432/db

# 第三方服務
RESEND_API_KEY=re_xxxx
GOOGLE_CLIENT_ID=xxxx.apps.googleusercontent.com

# 應用設定
NEXT_PUBLIC_API_URL=https://api.example.com

設定環境變數

方法一:Vercel Dashboard

  1. 進入專案的 Settings
  2. 點擊 Environment Variables
  3. 輸入 KeyValue
  4. 選擇適用的環境
  5. 點擊 Save

方法二:Vercel CLI

# 新增環境變數
vercel env add API_KEY

# 會提示輸入值和選擇環境
? What's the value of API_KEY? [hidden]
? Which Environments? (select multiple)
❯ ◉ Production
  ◉ Preview
  ◉ Development
# 拉取環境變數到本機
vercel env pull .env.local

方法三:vercel.json(不推薦敏感資料)

{
  "env": {
    "PUBLIC_CONFIG": "some-value"
  }
}

注意: vercel.json 會進 Git,不要放敏感資料。


三種環境

Vercel 有三種環境,環境變數可以針對不同環境設定不同值。

Production

正式環境,對應主分支的部署。

# 只在 Production 使用
STRIPE_SECRET_KEY=sk_live_xxxx

Preview

預覽環境,對應 PR 和非主分支的部署。

# 在 Preview 使用測試金鑰
STRIPE_SECRET_KEY=sk_test_xxxx

Development

開發環境,用於 vercel dev 本機開發。

# 開發用的設定
DEBUG=true

設定不同環境的值

在 Dashboard 中,可以為同一個變數設定不同環境的值:

變數名稱 Production Preview Development
API_URL https://api.example.com https://staging.api.example.com http://localhost:4000
DEBUG false true true

前端 vs 後端環境變數

後端環境變數(私密)

只能在伺服器端存取,不會暴露給瀏覽器。

// app/api/data/route.ts
export async function GET() {
  // 這只在伺服器執行,安全
  const apiKey = process.env.SECRET_API_KEY;

  const res = await fetch('https://api.example.com', {
    headers: { 'Authorization': apiKey },
  });

  return Response.json(await res.json());
}

前端環境變數(公開)

會被打包進 JavaScript,瀏覽器可以看到。

Next.js 規則: 前端變數必須以 NEXT_PUBLIC_ 開頭。

// 可以在前端使用
const apiUrl = process.env.NEXT_PUBLIC_API_URL;

// ❌ 這在前端會是 undefined
const secret = process.env.SECRET_KEY;

範例

# .env.local

# 後端專用(不要加 NEXT_PUBLIC_)
DATABASE_URL=postgresql://...
OPENAI_API_KEY=sk-...
JWT_SECRET=supersecret

# 前端可用(必須加 NEXT_PUBLIC_)
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_GA_ID=G-XXXXXX
NEXT_PUBLIC_APP_NAME=My App

本機開發

使用 .env.local

在專案根目錄建立 .env.local

# .env.local
DATABASE_URL=postgresql://localhost:5432/mydb
OPENAI_API_KEY=sk-xxxx
NEXT_PUBLIC_API_URL=http://localhost:3000

從 Vercel 拉取

vercel env pull .env.local

這會把 Vercel 上的環境變數下載到本機。

.env 檔案優先順序

Next.js 會按順序載入:

  1. .env.local(最高優先)
  2. .env.development.env.production
  3. .env(最低優先)

不要把 .env.local 推到 Git

# .gitignore
.env.local
.env*.local

動態環境變數

Build Time vs Runtime

Build Time: 在建置時注入,無法動態改變。

// 這會在 build 時被替換成實際值
const apiUrl = process.env.NEXT_PUBLIC_API_URL;

Runtime: 每次請求時讀取,可以動態改變。

// 在 API Route 中,每次請求都會讀取
export async function GET() {
  const apiKey = process.env.API_KEY; // Runtime
  // ...
}

使用 Runtime 環境變數

如果需要不重新部署就更改設定,使用外部服務:

  • Vercel Edge Config
  • 第三方 Feature Flag 服務

安全性最佳實踐

1. 永遠不要把密鑰放在前端

// ❌ 危險!
const secret = process.env.NEXT_PUBLIC_SECRET_KEY;

// ✅ 安全
const publicConfig = process.env.NEXT_PUBLIC_APP_NAME;

2. 使用環境特定的密鑰

# Production 用正式密鑰
STRIPE_SECRET_KEY=sk_live_xxxx

# Preview 用測試密鑰
STRIPE_SECRET_KEY=sk_test_xxxx

3. 定期輪換密鑰

定期更新 API Key,並更新 Vercel 環境變數。

4. 限制密鑰權限

在第三方服務中,只給予必要的權限。

5. 監控使用量

監控 API Key 的使用量,發現異常立即更換。


常見問題排解

問題一:環境變數讀不到

症狀: process.env.XXXundefined

檢查項目:

  1. 變數名稱是否正確(大小寫敏感)
  2. 是否在正確的環境設定
  3. 是否重新部署了(環境變數更改後需要重新部署)
  4. 前端變數是否有 NEXT_PUBLIC_ 前綴
// 偵錯
console.log('ENV:', process.env.MY_VAR);
console.log('All env:', Object.keys(process.env));

問題二:本機可以但部署失敗

可能原因:

  1. 只設了 Development 環境,沒設 Production
  2. .env.local 的值沒同步到 Vercel

解決方法:

# 確認 Vercel 上有設定
vercel env ls

問題三:Preview 環境出錯

可能原因:

Preview 環境使用不同的環境變數值。

檢查方法:

  1. 查看 Vercel Dashboard 的 Preview 環境設定
  2. 確認 Preview 有正確的設定

問題四:環境變數太多

解決方法:

使用 Vercel 的 Shared Environment Variables 功能:

  1. Settings → Shared Environment Variables
  2. 設定一次,多個專案共用

進階設定

使用 Vercel Edge Config

即時更新設定,不需要重新部署:

import { get } from '@vercel/edge-config';

export async function GET() {
  const featureEnabled = await get('new_feature_enabled');
  return Response.json({ featureEnabled });
}

從外部載入

// 從 Vault、AWS Secrets Manager 等載入
import { getSecret } from '@aws-sdk/client-secrets-manager';

export async function getSecretValue() {
  const secret = await getSecret({ SecretId: 'my-secret' });
  return secret.SecretString;
}

使用 dotenv 擴展

# 安裝
npm install dotenv-expand dotenv

# 使用
DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:5432/mydb

驗證環境變數

在 Build 時驗證

// lib/env.ts
const requiredEnvVars = [
  'DATABASE_URL',
  'OPENAI_API_KEY',
  'JWT_SECRET',
];

export function validateEnv() {
  const missing = requiredEnvVars.filter(
    (envVar) => !process.env[envVar]
  );

  if (missing.length > 0) {
    throw new Error(`Missing environment variables: ${missing.join(', ')}`);
  }
}
// app/layout.tsx
import { validateEnv } from '@/lib/env';

// 在 build 時執行
validateEnv();

使用 zod 驗證

import { z } from 'zod';

const envSchema = z.object({
  DATABASE_URL: z.string().url(),
  OPENAI_API_KEY: z.string().startsWith('sk-'),
  JWT_SECRET: z.string().min(32),
  NEXT_PUBLIC_API_URL: z.string().url(),
});

export const env = envSchema.parse({
  DATABASE_URL: process.env.DATABASE_URL,
  OPENAI_API_KEY: process.env.OPENAI_API_KEY,
  JWT_SECRET: process.env.JWT_SECRET,
  NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
});

常見問題 FAQ

Q1:環境變數更新後要重新部署嗎?

是的。Serverless Functions 需要重新部署才會讀到新值。

但可以用 Edge Config 實現不重新部署就更新。

Q2:有沒有環境變數數量限制?

Vercel 沒有硬性限制,但建議保持合理數量。

Q3:怎麼在 CI/CD 中使用?

Vercel 會自動使用設定的環境變數。

如果用 GitHub Actions,可以使用 Secrets。


Vercel 部署失敗?

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

解決 Vercel 問題


延伸閱讀

分享文章:
V

VibeFix

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

這篇文章有幫到你嗎?

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

聯繫我們