Vercel 環境變數設定完整教學|2025 最佳實踐指南
環境變數沒設好,部署就會出問題。
API Key 抓不到、資料庫連不上...
這篇文章教你如何正確設定 Vercel 環境變數。
什麼是環境變數?
環境變數是儲存在執行環境中的設定值。
為什麼需要環境變數?
- 安全性: API Key、密碼不放在程式碼中
- 彈性: 不同環境使用不同設定
- 方便: 不用改程式碼就能改設定
常見的環境變數
# 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
- 進入專案的 Settings
- 點擊 Environment Variables
- 輸入 Key 和 Value
- 選擇適用的環境
- 點擊 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 會按順序載入:
.env.local(最高優先).env.development或.env.production.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.XXX 是 undefined
檢查項目:
- 變數名稱是否正確(大小寫敏感)
- 是否在正確的環境設定
- 是否重新部署了(環境變數更改後需要重新部署)
- 前端變數是否有
NEXT_PUBLIC_前綴
// 偵錯
console.log('ENV:', process.env.MY_VAR);
console.log('All env:', Object.keys(process.env));
問題二:本機可以但部署失敗
可能原因:
- 只設了 Development 環境,沒設 Production
.env.local的值沒同步到 Vercel
解決方法:
# 確認 Vercel 上有設定
vercel env ls
問題三:Preview 環境出錯
可能原因:
Preview 環境使用不同的環境變數值。
檢查方法:
- 查看 Vercel Dashboard 的 Preview 環境設定
- 確認 Preview 有正確的設定
問題四:環境變數太多
解決方法:
使用 Vercel 的 Shared Environment Variables 功能:
- Settings → Shared Environment Variables
- 設定一次,多個專案共用
進階設定
使用 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、環境變數、自訂網域,我們幫你快速排除問題。