nextjs-env-variables
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNext.js Environment Variable Structure
Next.js环境变量结构
Complete guide to Next.js environment variable management.
Next.js环境变量管理完整指南。
File Structure
文件结构
my-nextjs-app/
├── .env # Shared defaults (committed)
├── .env.local # Local secrets (gitignored)
├── .env.development # Development defaults (committed)
├── .env.development.local # Local dev overrides (gitignored)
├── .env.production # Production defaults (committed)
├── .env.production.local # Production secrets (gitignored)
├── .env.test # Test environment (committed)
└── .env.example # Documentation (committed)my-nextjs-app/
├── .env # 共享默认配置(需提交至版本库)
├── .env.local # 本地密钥(需加入.gitignore忽略)
├── .env.development # 开发环境默认配置(需提交至版本库)
├── .env.development.local # 本地开发环境覆盖配置(需加入.gitignore忽略)
├── .env.production # 生产环境默认配置(需提交至版本库)
├── .env.production.local # 生产环境密钥(需加入.gitignore忽略)
├── .env.test # 测试环境配置(需提交至版本库)
└── .env.example # 配置文档(需提交至版本库)File Precedence
文件优先级
Next.js loads files in this order (higher = higher precedence):
- (e.g.,
.env.$(NODE_ENV).local).env.production.local - (not loaded in test environment)
.env.local - (e.g.,
.env.$(NODE_ENV)).env.production .env
Example: In production, if is defined in both and , the value from wins.
DATABASE_URL.env.env.production.local.env.production.localNext.js按以下顺序加载文件(位置越靠上优先级越高):
- (例如:
.env.$(NODE_ENV).local).env.production.local - (测试环境不加载)
.env.local - (例如:
.env.$(NODE_ENV)).env.production .env
示例:在生产环境中,如果同时在和中定义,则中的值会生效。
DATABASE_URL.env.env.production.local.env.production.localVariable Types
变量类型
Client-Side Variables (NEXT_PUBLIC_*)
客户端变量(NEXT_PUBLIC_*)
Exposed to the browser. Must prefix with .
NEXT_PUBLIC_bash
undefined会暴露至浏览器,必须以为前缀。
NEXT_PUBLIC_bash
undefined.env.local
.env.local
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_ANALYTICS_ID=UA-123456789
NEXT_PUBLIC_SITE_NAME=My Awesome Site
NEXT_PUBLIC_ENABLE_FEATURE_X=true
**Access in code**:
```javascript
// Works in both client and server
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
// Usage in components
export default function MyComponent() {
return <div>API: {process.env.NEXT_PUBLIC_API_URL}</div>;
}⚠️ Security Warning: NEVER put secrets in variables!
NEXT_PUBLIC_*bash
undefinedNEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_ANALYTICS_ID=UA-123456789
NEXT_PUBLIC_SITE_NAME=My Awesome Site
NEXT_PUBLIC_ENABLE_FEATURE_X=true
**代码中访问方式**:
```javascript
// 在客户端和服务端均可用
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
// 在组件中使用
export default function MyComponent() {
return <div>API: {process.env.NEXT_PUBLIC_API_URL}</div>;
}⚠️ 安全警告:绝对不要将密钥放入变量中!
NEXT_PUBLIC_*bash
undefined❌ WRONG - Secret exposed to browser
❌ 错误 - 密钥会暴露至浏览器
NEXT_PUBLIC_API_SECRET=sk_live_abc123
NEXT_PUBLIC_API_SECRET=sk_live_abc123
✅ CORRECT - Secret only on server
✅ 正确 - 密钥仅在服务端可用
API_SECRET=sk_live_abc123
undefinedAPI_SECRET=sk_live_abc123
undefinedServer-Side Variables
服务端变量
Only available in server-side code (API routes, getServerSideProps, etc.).
bash
undefined仅在服务端代码中可用(API路由、getServerSideProps等)。
bash
undefined.env.local
.env.local
DATABASE_URL=postgres://localhost:5432/mydb
JWT_SECRET=super-secret-jwt-key-do-not-expose
STRIPE_SECRET_KEY=sk_live_abc123
SMTP_PASSWORD=email-password-here
**Access in code**:
```javascript
// ✅ Works in API routes
export default async function handler(req, res) {
const dbUrl = process.env.DATABASE_URL;
// Use dbUrl...
}
// ✅ Works in getServerSideProps
export async function getServerSideProps() {
const secret = process.env.JWT_SECRET;
// Use secret...
}
// ❌ Does NOT work in components (browser)
export default function MyComponent() {
const dbUrl = process.env.DATABASE_URL; // undefined!
}DATABASE_URL=postgres://localhost:5432/mydb
JWT_SECRET=super-secret-jwt-key-do-not-expose
STRIPE_SECRET_KEY=sk_live_abc123
SMTP_PASSWORD=email-password-here
**代码中访问方式**:
```javascript
// ✅ 在API路由中可用
export default async function handler(req, res) {
const dbUrl = process.env.DATABASE_URL;
// 使用dbUrl...
}
// ✅ 在getServerSideProps中可用
export async function getServerSideProps() {
const secret = process.env.JWT_SECRET;
// 使用secret...
}
// ❌ 在组件中不可用(浏览器环境)
export default function MyComponent() {
const dbUrl = process.env.DATABASE_URL; // 结果为undefined!
}Example Files
示例文件
.env (Committed - Shared Defaults)
.env(已提交 - 共享默认配置)
bash
undefinedbash
undefinedShared defaults for all environments
所有环境共享的默认配置
NEXT_PUBLIC_APP_NAME=My Next.js App
NEXT_PUBLIC_DEFAULT_LOCALE=en
NEXT_PUBLIC_APP_NAME=My Next.js App
NEXT_PUBLIC_DEFAULT_LOCALE=en
Database (overridden in .env.local)
数据库配置(会被.env.local覆盖)
DATABASE_URL=postgres://localhost:5432/dev
DATABASE_URL=postgres://localhost:5432/dev
External services (no secrets)
外部服务配置(无密钥)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_abc123
undefinedNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_abc123
undefined.env.local (Gitignored - Local Secrets)
.env.local(已忽略 - 本地密钥)
bash
undefinedbash
undefinedLocal development secrets
本地开发环境密钥
DATABASE_URL=postgres://localhost:5432/mylocal
JWT_SECRET=dev-jwt-secret-change-in-production
STRIPE_SECRET_KEY=sk_test_local_key
DATABASE_URL=postgres://localhost:5432/mylocal
JWT_SECRET=dev-jwt-secret-change-in-production
STRIPE_SECRET_KEY=sk_test_local_key
Local overrides
本地覆盖配置
NEXT_PUBLIC_API_URL=http://localhost:4000/api
undefinedNEXT_PUBLIC_API_URL=http://localhost:4000/api
undefined.env.production (Committed - Production Defaults)
.env.production(已提交 - 生产环境默认配置)
bash
undefinedbash
undefinedProduction environment defaults
生产环境默认配置
NEXT_PUBLIC_API_URL=https://api.production.com
NEXT_PUBLIC_ANALYTICS_ID=UA-PROD-123456
NEXT_PUBLIC_API_URL=https://api.production.com
NEXT_PUBLIC_ANALYTICS_ID=UA-PROD-123456
These will be overridden by platform env vars
这些配置会被平台环境变量覆盖
DATABASE_URL=set-this-in-vercel
JWT_SECRET=set-this-in-vercel
undefinedDATABASE_URL=set-this-in-vercel
JWT_SECRET=set-this-in-vercel
undefined.env.example (Committed - Documentation)
.env.example(已提交 - 配置文档)
bash
undefinedbash
undefinedCopy this to .env.local and fill in actual values
复制此文件为.env.local并填入实际值
Client-side (browser accessible)
客户端变量(可被浏览器访问)
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_ANALYTICS_ID=your-analytics-id
NEXT_PUBLIC_SITE_NAME=Your Site Name
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_ANALYTICS_ID=your-analytics-id
NEXT_PUBLIC_SITE_NAME=Your Site Name
Server-side (secrets)
服务端变量(密钥)
DATABASE_URL=postgres://user:password@host:5432/database # pragma: allowlist secret
JWT_SECRET=your-jwt-secret-32-chars-minimum
STRIPE_SECRET_KEY=sk_live_your_stripe_key
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-email@example.com
SMTP_PASSWORD=your-smtp-password
undefinedDATABASE_URL=postgres://user:password@host:5432/database # pragma: allowlist secret
JWT_SECRET=your-jwt-secret-32-chars-minimum
STRIPE_SECRET_KEY=sk_live_your_stripe_key
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-email@example.com
SMTP_PASSWORD=your-smtp-password
undefinedCommon Patterns
常见模式
Database Configuration
数据库配置
bash
undefinedbash
undefinedDevelopment (.env.local)
开发环境(.env.local)
DATABASE_URL=postgres://localhost:5432/myapp_dev
DATABASE_URL=postgres://localhost:5432/myapp_dev
Production (Vercel Environment Variables)
生产环境(Vercel环境变量)
DATABASE_URL=postgres://user:pass@prod-host:5432/myapp_prod # pragma: allowlist secret
undefinedDATABASE_URL=postgres://user:pass@prod-host:5432/myapp_prod # pragma: allowlist secret
undefinedAPI Keys
API密钥
bash
undefinedbash
undefinedPublic keys (client-side)
公钥(客户端可用)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_abc123
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_abc123
Secret keys (server-side only)
密钥(仅服务端可用)
STRIPE_SECRET_KEY=sk_live_xyz789
undefinedSTRIPE_SECRET_KEY=sk_live_xyz789
undefinedFeature Flags
功能开关
bash
undefinedbash
undefinedToggle features
功能切换
NEXT_PUBLIC_ENABLE_DARK_MODE=true
NEXT_PUBLIC_ENABLE_BETA_FEATURES=false
undefinedNEXT_PUBLIC_ENABLE_DARK_MODE=true
NEXT_PUBLIC_ENABLE_BETA_FEATURES=false
undefinedDeployment to Vercel
部署至Vercel
Step 1: Add Environment Variables in Vercel
步骤1:在Vercel中添加环境变量
- Go to Project Settings → Environment Variables
- Add each variable:
- Key:
DATABASE_URL - Value:
postgres://... - Environments: Production, Preview, Development
- Key:
- 进入项目设置 → 环境变量
- 添加每个变量:
- 键:
DATABASE_URL - 值:
postgres://... - 环境:生产环境、预览环境、开发环境
- 键:
Step 2: Separate Client vs Server Variables
步骤2:区分客户端与服务端变量
Vercel automatically exposes variables at build time.
NEXT_PUBLIC_*bash
undefinedVercel会在构建时自动暴露变量。
NEXT_PUBLIC_*bash
undefinedVercel automatically handles:
Vercel会自动处理:
NEXT_PUBLIC_API_URL=https://api.example.com # ✅ Exposed to browser
NEXT_PUBLIC_API_URL=https://api.example.com # ✅ 暴露至浏览器
Server-only:
仅服务端可用:
DATABASE_URL=postgres://... # ✅ Not exposed to browser
undefinedDATABASE_URL=postgres://... # ✅ 不会暴露至浏览器
undefinedStep 3: Rebuild After Changing NEXT_PUBLIC_ Variables
步骤3:修改NEXT_PUBLIC_变量后重新构建
⚠️ Important: variables are baked into the build at build time.
NEXT_PUBLIC_*If changing them in Vercel, redeploy is required:
bash
vercel --prod⚠️ 重要提示:变量会在构建时嵌入到应用中。
NEXT_PUBLIC_*如果在Vercel中修改了这些变量,需要重新部署:
bash
vercel --prodValidation Workflow
验证流程
1. Validate Local Environment
1. 验证本地环境
bash
undefinedbash
undefinedCheck structure
检查结构
python scripts/validate_env.py .env.local --framework nextjs
python scripts/validate_env.py .env.local --framework nextjs
Compare with .env.example
与.env.example对比
python scripts/validate_env.py .env.local --compare-with .env.example
python scripts/validate_env.py .env.local --compare-with .env.example
Check for security issues
检查安全问题
python scripts/scan_exposed.py --check-gitignore
undefinedpython scripts/scan_exposed.py --check-gitignore
undefined2. Check File Precedence
2. 检查文件优先级
bash
undefinedbash
undefinedList all .env files
列出所有.env文件
ls -la .env*
ls -la .env*
Validate each
逐个验证
for file in .env*; do
echo "=== $file ==="
python scripts/validate_env.py $file --framework nextjs
done
undefinedfor file in .env*; do
echo "=== $file ==="
python scripts/validate_env.py $file --framework nextjs
done
undefined3. Sync to Vercel
3. 同步至Vercel
bash
undefinedbash
undefinedCompare local vs Vercel
对比本地与Vercel的变量
python scripts/sync_secrets.py --platform vercel --compare
python scripts/sync_secrets.py --platform vercel --compare
Sync (dry-run first)
同步(先进行试运行)
python scripts/sync_secrets.py --platform vercel --sync --dry-run
python scripts/sync_secrets.py --platform vercel --sync --dry-run
Actually sync
实际同步
python scripts/sync_secrets.py --platform vercel --sync --confirm
undefinedpython scripts/sync_secrets.py --platform vercel --sync --confirm
undefinedCommon Issues
常见问题
Issue: Variable Undefined in Browser
问题:变量在浏览器中显示为Undefined
Symptom: is in component.
process.env.MY_VARundefinedSolution: Add prefix:
NEXT_PUBLIC_bash
undefined症状:在组件中的值为。
process.env.MY_VARundefined解决方案:添加前缀:
NEXT_PUBLIC_bash
undefined❌ Wrong
❌ 错误
API_URL=https://api.example.com
API_URL=https://api.example.com
✅ Correct
✅ 正确
NEXT_PUBLIC_API_URL=https://api.example.com
undefinedNEXT_PUBLIC_API_URL=https://api.example.com
undefinedIssue: Changed Variable Not Reflected
问题:修改变量后未生效
Symptom: Changed variable in Vercel, but app still uses old value.
NEXT_PUBLIC_*Solution: Redeploy (variables are baked into build):
bash
vercel --prod症状:在Vercel中修改了变量,但应用仍使用旧值。
NEXT_PUBLIC_*解决方案:重新部署(变量在构建时已嵌入应用):
bash
vercel --prodIssue: Works Locally, Not in Production
问题:本地正常运行,生产环境出错
Symptom: App works with , fails in production.
.env.localSolution: Ensure all variables from are set in Vercel:
.env.localbash
undefined症状:应用在本地使用正常运行,但在生产环境中失败。
.env.local解决方案:确保中的所有变量都已在Vercel中设置:
.env.localbash
undefinedCompare
对比
python scripts/sync_secrets.py --platform vercel --compare
python scripts/sync_secrets.py --platform vercel --compare
Find missing vars and add them in Vercel UI
找出缺失的变量并在Vercel界面中添加
undefinedundefinedSecurity Checklist
安全检查清单
- in
.env.local.gitignore - in
.env.*.local.gitignore - No secrets in variables
NEXT_PUBLIC_* - No files committed with real secrets
.env - has structure, not actual values
.env.example - Secrets set directly in Vercel (not in committed files)
- 已加入
.env.local.gitignore - 已加入
.env.*.local.gitignore - 变量中无密钥
NEXT_PUBLIC_* - 已提交的文件中无真实密钥
.env - 仅包含结构,无实际值
.env.example - 密钥直接在Vercel中设置(而非在已提交的文件中)
References
参考资料
Related: validation.md | security.md | frameworks.md
Related Skills
相关技能
When using Nextjs, these skills enhance your workflow:
- react: Core React patterns and hooks for Next.js components
- tanstack-query: Server-state management with App Router and Server Components
- drizzle: Type-safe ORM for Next.js server actions and API routes
- prisma: Alternative ORM with excellent Next.js integration
- test-driven-development: Testing Next.js App Router, Server Components, and API routes
[Full documentation available in these skills if deployed in your bundle]
使用Next.js时,以下技能可提升你的工作流:
- react:Next.js组件的核心React模式与钩子
- tanstack-query:App Router与Server Components的服务端状态管理
- drizzle:适用于Next.js服务端操作与API路由的类型安全ORM
- prisma:与Next.js集成良好的替代ORM
- test-driven-development:测试Next.js App Router、Server Components与API路由
[如果部署在你的技能包中,可查看完整文档]