Loading...
Loading...
Loading...
Environment variable validation ด้วย Zod + server-only — fail fast ตอน startup, type-safe ตลอด project
ทำไมต้อง validate environment variables? — Zod safeParse + fail fast pattern
ปัญหาถ้าไม่ validate env
Zod validation แก้ปัญหาทั้งหมด
validate server-side env ด้วย Zod + ป้องกัน import ใน Client ด้วย server-only
Key Points
import 'server-only' — Client Component import ไฟล์นี้ → build error ทันที ป้องกัน secret leakprocess.exit(1) — fail fast ตอน startup — ไม่ใช่ตอน user เข้าหน้า (ใช้ได้เฉพาะ server)z.prettifyError() — แสดง error message อ่านง่าย — บอกชัดว่า key ไหนผิด/ขาดSchema Fields (ตัวอย่างในโปรเจคนี้)
| Key | Validation | Description |
|---|---|---|
API_URL | string (url) | Backend API endpoint |
AUTH_SECRET | string (min 10) | Secret สำหรับ sign JWT/session |
NODE_ENV | enum + default | development | production | test |
validate client-side env + gotcha สำคัญ: ต้อง reference process.env.NEXT_PUBLIC_XXX ทีละตัว
Gotcha: process.env ใน browser = {}
Next.js จะ inline ค่า NEXT_PUBLIC_* ตอน build — แต่ทำได้เฉพาะเมื่อเขียน process.env.NEXT_PUBLIC_XXX ตรงๆ ทีละตัว
WRONG
schema.safeParse(process.env)
// browser: process.env = {}
// ทุก key เป็น undefined!CORRECT
schema.safeParse({
NEXT_PUBLIC_BASE_URL:
process.env.NEXT_PUBLIC_BASE_URL,
})
// Next.js inline ค่าจริงต่างจาก Server Env อย่างไร
server-only — ใช้ได้ทั้ง Server และ Clientthrow Error แทน process.exit — browser ไม่มี process.exitprocess.env.NEXT_PUBLIC_XXX ทีละตัว.env / .env.local / .env.example — ใครทำอะไร, priority, gitignore
Priority (สูง → ต่ำ)
| # | File | Git | Description |
|---|---|---|---|
| 3 | .env | commit | ค่า default ทุก environment — commit ได้ |
| 1 | .env.local | gitignore | Secret + override — ห้าม commit! |
| 2 | .env.development | commit | Override เฉพาะ dev mode |
| 2 | .env.production | commit | Override เฉพาะ production |
| - | .env.example | commit | Template สำหรับ team — commit ได้ |
Override ทำงานยังไง?
.env → API_URL=http://localhost:3001
.env.local → API_URL=https://staging.example.com
ผลลัพธ์: API_URL = "https://staging.example.com"
(.env.local override .env)วิธีเรียกใช้ serverEnv / clientEnv ใน Server Component, Client Component, Server Action
serverEnvfetch(serverEnv.API_URL + "/api/features")clientEnvnew WebSocket(clientEnv.NEXT_PUBLIC_SOCKET_URL)serverEnvfetch(serverEnv.API_URL + "/api/auth/login")ห้ามทำ
serverEnv ใน Client Component — build error — server-only guardprocess.env.API_URL ตรงๆ — string | undefined — ไม่มี type safetyprocess.env.APIURL (typo) — ไม่มี error ตอน compile — พังตอน runtime