27. Environment Variables Management
Dalam pengembangan aplikasi web modern, variabel lingkungan (environment variables atau env vars) digunakan untuk memisahkan konfigurasi aplikasi dari kode sumber (source code). Langkah ini sangat penting untuk menjaga keamanan kredensial sensitif, menyederhanakan konfigurasi di berbagai lingkungan (local, development, staging, production), dan mendukung prinsip Twelve-Factor App.
Dokumentasi ini menjelaskan secara mendalam konsep, hierarki, dan praktik terbaik manajemen variabel lingkungan di Next.js.
A. Client-Side vs Server-Side Variables (Prefixing)
Next.js secara cerdas memisahkan variabel lingkungan berdasarkan tempat eksekusinya. Secara default, variabel lingkungan di Next.js hanya tersedia di sisi server (Node.js runtime) untuk mencegah kebocoran data sensitif ke browser pengguna.
1. Perbedaan Utama
| Kriteria | NEXT_PUBLIC_ Prefix | Tanpa Prefix (Private) |
|---|---|---|
| Aksesibilitas | Sisi Server & Sisi Klien (Browser) | Hanya Sisi Server (Node.js runtime) |
| Keamanan | Rendah (Dapat dilihat oleh siapa saja melalui devtools/bundle) | Tinggi (Tersembunyi di balik server) |
| Metode Evaluasi | Di-inline/diganti secara statis saat build-time | Dibaca secara dinamis saat runtime di server |
| Contoh Penggunaan | URL API Publik, ID Google Analytics, Client Key | API Key Stripe, Database URL, JWT Secret Key |
2. Cara Kerja Penggantian Statis (Static Replacement)
Untuk variabel dengan awalan NEXT_PUBLIC_, compiler Next.js akan mendeteksi referensi ke variabel tersebut dan menggantinya dengan nilai konkret saat proses build dilakukan.
// Kode sumber sebelum build:
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
// Kode JavaScript hasil build yang dikirim ke browser:
const apiUrl = "https://api.produksi-anda.com";
[!CAUTION] Jangan pernah memberikan awalan
NEXT_PUBLIC_pada kunci API pribadi, kredensial database, atau token akses sensitif. Nilai apa pun yang diawali denganNEXT_PUBLIC_akan di-bundle ke dalam berkas JavaScript client-side dan dapat dibaca dengan mudah oleh siapa saja melalui Developer Tools browser.
B. Hierarki & Urutan Prioritas File .env
Next.js memiliki mekanisme membawaan untuk membaca berbagai file .env berdasarkan status environment aktif (development, production, atau testing).
1. Jenis-Jenis File Konfigurasi .env
.env: Konfigurasi default untuk semua environment..env.local: Konfigurasi lokal yang mengesampingkan (override) pengaturan default di.env. File ini wajib dimasukkan ke dalam.gitignorekarena biasanya berisi kredensial lokal developer..env.development: Konfigurasi khusus untuk tahap pengembangan (next dev)..env.development.local: Pengesampingan konfigurasi development lokal yang bersifat sensitif..env.production: Konfigurasi khusus untuk tahap build produksi (next build&next start)..env.production.local: Pengesampingan konfigurasi produksi lokal yang bersifat sensitif..env.test: Konfigurasi khusus untuk pengujian (jest,cypress, dll).
2. Prioritas Pemuatan (Load Order)
Next.js mengevaluasi file .env dari prioritas tertinggi ke terendah. Jika variabel yang sama didefinisikan di beberapa file, nilai dari file dengan prioritas lebih tinggi yang akan digunakan.
| Urutan Prioritas | Saat Mode Pengembangan (next dev) | Saat Mode Produksi (next build / start) |
|---|---|---|
| 1 (Tertinggi) | .env.development.local | .env.production.local |
| 2 | .env.local | .env.local |
| 3 | .env.development | .env.production |
| 4 (Terendah) | .env | .env |
[!WARNING] File
.env.localtidak akan dibaca dalam fase pengujian (next testatau saat menggunakan variabelNODE_ENV=test) untuk memastikan hasil pengujian tetap konsisten dan tidak dipengaruhi oleh modifikasi lokal developer. Gunakan.env.testatau.env.test.localuntuk konfigurasi testing.
C. Alur Evaluasi Variabel Lingkungan
Mermaid diagram di bawah mengilustrasikan bagaimana Next.js mengevaluasi variabel lingkungan dari kode sumber hingga sampai ke browser atau tetap aman di server:
graph TD
A[Mulai Eksekusi Aplikasi / Build] --> B{Fase Proses?}
B -- Build Time / Client Bundling --> C{Apakah Variabel Berawalan NEXT_PUBLIC_?}
C -- Ya --> D[Ganti process.env.NEXT_PUBLIC_... dengan nilai asli secara statis]
D --> E[Simpan ke Client-Side JS Bundle]
E --> F[Dapat diakses di Browser]
C -- Tidak --> G[Abaikan di Sisi Klien - Nilai diganti dengan undefined]
B -- Runtime di Sisi Server --> H{Apakah Variabel Tersedia di .env / OS env?}
H -- Ya --> I[Dapat diakses via process.env.KEY]
H -- Tidak --> J[Bernilai undefined]
I --> K[Hanya dapat diakses di Server Components, API Routes, getServerSideProps]
D. Praktik Terbaik & Gotchas (Hal Penting yang Sering Terlewat)
1. Masukkan File .local ke .gitignore
Selalu pastikan file .local (seperti .env.local, .env.development.local, .env.production.local) terdaftar di .gitignore. File-file tersebut menyimpan konfigurasi spesifik developer dan kredensial rahasia yang tidak boleh masuk ke repositori git publik maupun privat.
# .gitignore
.env*.local
2. Sediakan File .env.example
Untuk memudahkan kolaborasi dengan developer lain, buat file .env.example di root proyek. Tulis semua nama variabel yang dibutuhkan oleh aplikasi tanpa menyertakan nilai rahasianya.
# .env.example
DATABASE_URL=mongodb://localhost:27017/mydb
NEXT_PUBLIC_API_URL=https://api.example.com
STRIPE_PUBLIC_KEY=pk_test_...
STRIPE_SECRET_KEY= # Jangan sertakan nilai rahasia di file ini!
3. Larangan Destrukturisasi Dinamis pada Client-Side
Karena Next.js melakukan penggantian statis (static replacement) menggunakan AST parsing saat build time untuk kode client-side, Anda tidak boleh melakukan destrukturisasi pada process.env.
// ❌ HINDARI (Tidak akan berfungsi di Client-side / bernilai undefined):
const { NEXT_PUBLIC_API_URL, NEXT_PUBLIC_ANALYTICS_ID } = process.env;
// SELALU GUNAKAN (Bekerja dengan benar):
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
const analyticsId = process.env.NEXT_PUBLIC_ANALYTICS_ID;
E. Validasi Variabel Lingkungan dengan Type-Safe (Zod)
Salah satu masalah klasik dalam pengembangan aplikasi adalah aplikasi gagal berjalan di server produksi hanya karena satu variabel lingkungan lupa didefinisikan atau salah ketik (typo). Kita bisa menggunakan Zod untuk memvalidasi seluruh variabel lingkungan saat aplikasi dijalankan (fail-fast mechanism).
1. Implementasi Skema Validasi (lib/env.ts)
Buat berkas utilitas untuk memvalidasi variabel lingkungan:
import { z } from "zod";
const envSchema = z.object({
// Sisi Server (Wajib diisi saat runtime server)
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(8),
// Sisi Klien (Wajib diawali NEXT_PUBLIC_)
NEXT_PUBLIC_API_URL: z.string().url(),
NEXT_PUBLIC_APP_ENV: z.enum(["development", "production", "test"]),
});
// Lakukan validasi terhadap process.env
const parseResult = envSchema.safeParse(process.env);
if (!parseResult.success) {
console.error("❌ Kesalahan Konfigurasi Variabel Lingkungan:");
console.error(JSON.stringify(parseResult.error.format(), null, 2));
throw new Error("Variabel lingkungan tidak valid. Periksa konfigurasi Anda!");
}
export const env = parseResult.data;
2. Cara Menggunakan Variabel yang Tervalidasi
Alih-alih memanggil process.env.NEXT_PUBLIC_API_URL secara langsung di seluruh codebase (yang rentan typo dan bertipe string | undefined), impor objek env yang sudah tervalidasi dan memiliki tipe data yang jelas (type-safe).
import { env } from "@/lib/env";
export default function MyComponent() {
// Autocomplete IDE akan aktif dan menjamin tipe data string
const apiUrl = env.NEXT_PUBLIC_API_URL;
return <div>URL API: {apiUrl}</div>;
}
[!TIP] Di ekosistem Next.js, terdapat pustaka populer bernama
@t3-oss/env-nextjsyang membungkus logika validasi ini dengan sangat baik untuk memisahkan variabel client-side dan server-side secara ketat.
F. Referensi Tambahan
- Next.js Official Docs - Environment Variables: Dokumentasi resmi Next.js mengenai cara konfigurasi, penanganan build-time vs runtime, dan optimasi pemuatan.
- T3 Env Docs: Dokumentasi resmi
@t3-oss/env-nextjsuntuk pengelolaan variabel lingkungan type-safe di Next.js. - Twelve-Factor App - Config: Metodologi standar industri mengenai penyimpanan konfigurasi di dalam environment.