Environment และ Configuration
ไอเดียในหนึ่งประโยค
หัวข้อที่มีชื่อว่า “ไอเดียในหนึ่งประโยค”env var เป็น server-only เป็น default มีแค่ตัวที่ขึ้นต้นด้วย NEXT_PUBLIC_ เท่านั้นที่ถูก inline เข้า client bundle เพราะฉะนั้น secret ห้ามมี prefix นั้นเด็ดขาด
Server-only versus NEXT_PUBLIC_
หัวข้อที่มีชื่อว่า “Server-only versus NEXT_PUBLIC_”env var ธรรมดาใช้ได้แค่ฝั่ง server พอใส่ prefix NEXT_PUBLIC_ Next.js จะ inline ค่านั้นเข้าไปใน JavaScript ที่ส่งไป browser ตอน build เหมาะกับ analytics id สาธารณะ แต่หายนะถ้าเป็น API secret
// Server Component or route — both work on the serverconst dbUrl = process.env.DATABASE_URL // server-only, safeconst analyticsId = process.env.NEXT_PUBLIC_ANALYTICS_ID // also in the client bundleDATABASE_URL="postgres://user:pass@host:5432/db" # never prefix a secretNEXT_PUBLIC_ANALYTICS_ID="abcdefghijk" # safe to exposeเพราะค่า NEXT_PUBLIC_ ถูกฝังตอน build การเปลี่ยนค่าแปลว่าต้อง rebuild ใหม่ ไม่ได้อ่านตอน runtime บน browser
.env files and load order
หัวข้อที่มีชื่อว่า “.env files and load order”Next.js โหลดไฟล์ .env หลายตัวและตัวที่ match ก่อนชนะ สำหรับ production ลำดับคือ .env.production.local แล้ว .env.local แล้ว .env.production แล้ว .env เก็บ secret ไว้ใน .env.local (gitignore) แล้ว commit เฉพาะ default ที่ปลอดภัย
.env # committed defaults, safe values only.env.local # gitignored, real secrets.env.development # loaded during next dev.env.production # loaded during next build / next startnext.config.ts essentials
หัวข้อที่มีชื่อว่า “next.config.ts essentials”next.config.ts คือที่ที่เรา config ตัว framework เอง สี่ตัวที่ใช้บ่อยสุดคือ images.remotePatterns (อนุญาต image host ภายนอก), redirects, rewrites และ headers
import type { NextConfig } from 'next'
const nextConfig: NextConfig = { images: { remotePatterns: [ { protocol: 'https', hostname: 's3.amazonaws.com', pathname: '/my-bucket/**' }, ], }, async redirects() { return [{ source: '/about', destination: '/', permanent: true }] }, async rewrites() { return [{ source: '/docs/:slug', destination: '/help/:slug' }] }, async headers() { return [ { source: '/(.*)', headers: [{ key: 'X-Frame-Options', value: 'DENY' }], }, ] },}
export default nextConfiggraph TD A["process.env.SECRET"] --> B["Server only"] C["process.env.NEXT_PUBLIC_ID"] --> B C --> D["Inlined into client bundle at build time"]