Environment Variables — .env, .env.local, .env.production
Muammodan boshlaylik
const stripe = new Stripe('sk_live_51Hx...')
const db = 'postgresql://admin:Parol123@db.dokon.uz/prod'
Maxfiy kalitlar kodda — va kod GitHub da. Bundan tashqari:
- Development da test kalitlari, production da haqiqiylari kerak
- Ba'zi qiymatlar brauzerga kerak (Google Analytics ID), ba'zilari hech qachon brauzerga ketmasligi kerak (bazaga parol)
- Yangi dasturchi loyihani ishga tushirish uchun qaysi o'zgaruvchilar kerakligini bilmaydi
Hayotiy o'xshatma
Mehmonxona kalitlari. Xona raqami (ochiq qiymat) — hamma ko'rishi mumkin, eshikda yozilgan. Seyf kodi (maxfiy kalit) — faqat sizda. Har bir mehmonga (muhitga) — o'z kodi. Seyf kodini eshikka yozib qo'ymaysiz.
.env fayllari
| Fayl | Qachon yuklanadi | Git ga |
|---|---|---|
.env |
Hamma muhitda | ✅ (maxfiy bo'lmagan standart qiymatlar) |
.env.local |
Hamma muhitda (test dan tashqari), ustidan yozadi |
❌ |
.env.development |
next dev |
✅ |
.env.production |
next build, next start |
✅ |
.env.development.local, .env.production.local |
Shu muhit, eng yuqori ustuvorlik | ❌ |
.env.test |
NODE_ENV=test (Vitest) |
✅ |
Ustuvorlik (yuqoridan pastga): process.env (tizim) → .env.$(NODE_ENV).local → .env.local → .env.$(NODE_ENV) → .env.
# .env.local — sizning shaxsiy, git da emas
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/dokon"
AUTH_SECRET="development-uchun-tasodifiy-satr"
STRIPE_SECRET_KEY="sk_test_..."
NEXT_PUBLIC_SITE_URL="http://localhost:3000"
create-next-app .gitignore ga .env* ni allaqachon qo'shgan.
Server va brauzer
Faqat server — oddiy nom
// Server Component, Route Handler, Server Action
const db = process.env.DATABASE_URL
Brauzerga hech qachon ketmaydi. Client Component da process.env.DATABASE_URL — undefined.
Brauzer uchun — NEXT_PUBLIC_
NEXT_PUBLIC_SITE_URL="https://dokon.uz"
NEXT_PUBLIC_GA_ID="G-XXXXXXX"
'use client'
const url = process.env.NEXT_PUBLIC_SITE_URL
NEXT_PUBLIC_o'zgaruvchilar build paytida JavaScript ga matn sifatida yoziladi- Ularni o'zgartirish — qayta build talab qiladi
- Ular ochiq: har kim brauzer kodida ko'radi
[!WARNING]
NEXT_PUBLIC_prefiksini maxfiy kalitga hech qachon qo'ymang:NEXT_PUBLIC_STRIPE_SECRET_KEY,NEXT_PUBLIC_DATABASE_URL,NEXT_PUBLIC_OPENAI_KEY— bu kalitni butun dunyoga e'lon qilish. Brauzerga faqat ochiq qiymatlar: sayt manzili, analitika ID, publishable (ochiq) kalitlar.
Dinamik o'qish — runtime
NEXT_PUBLIC_ qiymatlari build da "muzlatiladi". Bitta Docker image ni turli muhitlarda (staging, production) ishlatmoqchi bo'lsangiz — bu muammo. Yechim: qiymatni serverda o'qib, client ga uzatish:
// app/layout.tsx (Server Component)
export default function RootLayout({ children }: { children: React.ReactNode }) {
const sozlama = { saytUrl: process.env.SITE_URL, gaId: process.env.GA_ID }
return (
<html lang="uz">
<body>
<SozlamaProvider qiymat={sozlama}>{children}</SozlamaProvider>
</body>
</html>
)
}
Dinamik render qilinadigan sahifalarda server o'zgaruvchilari so'rov paytida o'qiladi.
Tekshirish — Zod bilan
// lib/env.ts
import 'server-only'
import { z } from 'zod'
const schema = z.object({
DATABASE_URL: z.string().url(),
AUTH_SECRET: z.string().min(32),
STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
NODE_ENV: z.enum(['development', 'test', 'production']),
})
export const env = schema.parse(process.env)
import { env } from '@/lib/env'
const stripe = new Stripe(env.STRIPE_SECRET_KEY)
O'zgaruvchi yo'q yoki noto'g'ri bo'lsa — ilova darhol aniq xato bilan to'xtaydi, yarim tunda emas. @t3-oss/env-nextjs paketi server/client o'zgaruvchilarini alohida tekshirish va client da server o'zgaruvchisiga murojaatni taqiqlash imkonini beradi.
Jamoa uchun — .env.example
# .env.example — git da, qiymatlarsiz
DATABASE_URL=
AUTH_SECRET= # npx auth secret
STRIPE_SECRET_KEY= # Stripe Dashboard → Developers → API keys (test)
NEXT_PUBLIC_SITE_URL=http://localhost:3000
Yangi dasturchi: cp .env.example .env.local → qiymatlarni to'ldiradi.
Production da
Production serverda .env fayllar odatda ishlatilmaydi — o'zgaruvchilar platforma orqali beriladi:
| Platforma | Qayerda |
|---|---|
| Vercel | Project → Settings → Environment Variables (66-dars) |
| Docker | docker run --env-file, Compose environment (67-dars) |
| VPS | PM2 ecosystem.config.js, systemd EnvironmentFile (68-dars) |
| GitHub Actions | Repository Secrets (69-dars) |
[!TIP] Vercel da:
vercel env pull .env.local— platformadagi development o'zgaruvchilarini lokal faylga tortib oladi. Jamoa bir xil sozlamalar bilan ishlaydi.
Tez-tez uchraydigan xatolar
1. Client da undefined
process.env.API_URL Client Component da — NEXT_PUBLIC_ prefiksi yo'q. Lekin maxfiy bo'lsa — prefiks qo'shmang, serverda ishlating.
2. .env.local ni o'zgartirib, serverni qayta ishga tushirmaslik
next dev o'zgaruvchilarni ishga tushishda o'qiydi (ba'zi versiyalar .env ni qayta yuklaydi, lekin ishonmang).
3. Kalit git tarixida
Faylni o'chirish yetmaydi — kalit tarixda qoladi. Kalitni almashtiring (rotate).
4. Dinamik kalit nomi
// ❌ — build da almashtirilmaydi
process.env[`NEXT_PUBLIC_${nom}`]
// ✅ — to'liq nom
process.env.NEXT_PUBLIC_GA_ID
Xulosa
.env (standart) → .env.local (shaxsiy, git da emas) → .env.[muhit] → .local
Oddiy nom — faqat server; NEXT_PUBLIC_ — brauzerga, build da yoziladi, OCHIQ
Maxfiy kalit — hech qachon NEXT_PUBLIC_ emas
Runtime qiymat client ga — server da o'qib, prop/provider orqali
Zod bilan tekshirish — darhol aniq xato
.env.example — jamoa uchun; production — platforma sozlamalari
Sizib chiqqan kalit — almashtiring
Keyingi dars
66-dars: Vercel — deploy qilish, environment, domain sozlash
Next.js ni yaratuvchilarning platformasiga bir necha daqiqada joylash.