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

KriteriaNEXT_PUBLIC_ PrefixTanpa Prefix (Private)
AksesibilitasSisi Server & Sisi Klien (Browser)Hanya Sisi Server (Node.js runtime)
KeamananRendah (Dapat dilihat oleh siapa saja melalui devtools/bundle)Tinggi (Tersembunyi di balik server)
Metode EvaluasiDi-inline/diganti secara statis saat build-timeDibaca secara dinamis saat runtime di server
Contoh PenggunaanURL API Publik, ID Google Analytics, Client KeyAPI 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 dengan NEXT_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

  1. .env: Konfigurasi default untuk semua environment.
  2. .env.local: Konfigurasi lokal yang mengesampingkan (override) pengaturan default di .env. File ini wajib dimasukkan ke dalam .gitignore karena biasanya berisi kredensial lokal developer.
  3. .env.development: Konfigurasi khusus untuk tahap pengembangan (next dev).
  4. .env.development.local: Pengesampingan konfigurasi development lokal yang bersifat sensitif.
  5. .env.production: Konfigurasi khusus untuk tahap build produksi (next build & next start).
  6. .env.production.local: Pengesampingan konfigurasi produksi lokal yang bersifat sensitif.
  7. .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 PrioritasSaat 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.local tidak akan dibaca dalam fase pengujian (next test atau saat menggunakan variabel NODE_ENV=test) untuk memastikan hasil pengujian tetap konsisten dan tidak dipengaruhi oleh modifikasi lokal developer. Gunakan .env.test atau .env.test.local untuk 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-nextjs yang membungkus logika validasi ini dengan sangat baik untuk memisahkan variabel client-side dan server-side secara ketat.


F. Referensi Tambahan

© 2026 Bit Group Asia. All rights reserved.

ArchitectureSecurityGuidelines