Environment variable adalah salah satu mekanisme dasar untuk menyimpan konfigurasi aplikasi tanpa menaruh nilainya langsung di source code. Dalam proyek SvelteKit, topik ini penting karena aplikasi berjalan di dua sisi: server dan client. Kesalahan kecil saat membaca atau mengekspos variabel environment bisa berujung pada kebocoran rahasia seperti API secret, token backend, atau kredensial layanan pihak ketiga.
SvelteKit menyediakan modul bawaan untuk membaca environment variable dengan pendekatan yang cukup ketat dan aman. Alih-alih membaca langsung dari process.env di semua tempat, SvelteKit membagi akses menjadi beberapa modul seperti $env/static/private, $env/static/public, $env/dynamic/private, dan $env/dynamic/public. Pembagian ini membantu memastikan variabel yang sensitif hanya dipakai di server, sementara variabel yang memang aman untuk browser dapat diakses dari sisi client.
Artikel ini fokus pada praktik yang paling sering dibutuhkan: cara menaruh nilai di file .env, perbedaan static dan dynamic, kapan memakai public atau private, serta contoh implementasi yang aman untuk API base URL dan public key.
Dasar file .env di SvelteKit
Secara umum, file .env dipakai untuk mendefinisikan konfigurasi per lingkungan, misalnya development, staging, atau production. SvelteKit memuat environment variable dari file semacam ini dan menyediakan antarmuka yang lebih aman untuk mengaksesnya.
Contoh file .env sederhana:
PRIVATE_API_BASE_URL=https://internal-api.example.com
PUBLIC_API_BASE_URL=https://api.example.com
PUBLIC_ANALYTICS_KEY=pk_live_123456
PRIVATE_SERVICE_TOKEN=super-secret-tokenDari contoh di atas:
PRIVATE_API_BASE_URLdanPRIVATE_SERVICE_TOKENseharusnya hanya dipakai di server.PUBLIC_API_BASE_URLdanPUBLIC_ANALYTICS_KEYaman untuk diekspos ke browser karena memang dirancang sebagai konfigurasi publik.
Konvensi penting di SvelteKit adalah prefix PUBLIC_. Variabel dengan prefix ini boleh diakses dari client. Sebaliknya, variabel tanpa prefix tersebut dianggap privat dan hanya boleh diakses pada konteks server.
Catatan penting: jangan menganggap file
.envsebagai tempat aman untuk data sensitif jika file itu ikut ter-commit ke repository. Biasanya file ini dimasukkan ke.gitignore, dan nilai production dikelola melalui sistem deployment seperti Vercel, Netlify, Docker, Kubernetes, atau platform CI/CD.
Mengenal modul env di SvelteKit
SvelteKit membagi akses env menjadi empat modul utama. Memahami pembagian ini jauh lebih penting daripada sekadar menghafal nama modulnya, karena tiap modul punya implikasi keamanan dan perilaku build yang berbeda.
$env/static/private
Modul ini dipakai untuk environment variable privat yang diketahui saat proses build. Variabel dari modul ini hanya dapat digunakan di kode server, misalnya di +page.server.ts, +layout.server.ts, +server.ts, hooks server, atau modul backend lain yang tidak dikirim ke browser.
import { PRIVATE_API_BASE_URL, PRIVATE_SERVICE_TOKEN } from '$env/static/private';
console.log(PRIVATE_API_BASE_URL);
console.log(PRIVATE_SERVICE_TOKEN);Kelebihannya adalah nilai bisa dioptimasi saat build dan aksesnya eksplisit. Ini sering menjadi pilihan terbaik untuk konfigurasi backend yang stabil.
$env/static/public
Modul ini dipakai untuk environment variable publik yang diketahui saat build dan aman dikirim ke browser. Hanya variabel dengan prefix PUBLIC_ yang tersedia di sini.
import { PUBLIC_API_BASE_URL, PUBLIC_ANALYTICS_KEY } from '$env/static/public';
console.log(PUBLIC_API_BASE_URL);
console.log(PUBLIC_ANALYTICS_KEY);Gunakan modul ini untuk nilai seperti URL API publik, nama environment yang tidak sensitif, atau public key dari layanan frontend. Karena nilainya bisa masuk ke bundle client, jangan pernah menaruh secret di sini.
$env/dynamic/private
Modul ini dipakai untuk membaca environment variable privat secara dinamis pada saat runtime, bukan di-hardcode saat build. Biasanya bentuknya berupa objek env.
import { env } from '$env/dynamic/private';
console.log(env.PRIVATE_API_BASE_URL);
console.log(env.PRIVATE_SERVICE_TOKEN);Pendekatan dynamic berguna jika nilai environment bisa berbeda antar instance runtime atau tidak ingin dibekukan saat build. Trade-off-nya, hasilnya biasanya kurang optimal dibanding static dan tidak seketat impor bernama satu per satu.
$env/dynamic/public
Modul ini dipakai untuk membaca environment variable publik secara runtime. Aksesnya juga melalui objek env, tetapi hanya untuk variabel yang berprefix PUBLIC_.
import { env } from '$env/dynamic/public';
console.log(env.PUBLIC_API_BASE_URL);
console.log(env.PUBLIC_ANALYTICS_KEY);Modul ini berguna jika konfigurasi publik perlu lebih fleksibel pada runtime. Namun untuk kebutuhan umum, $env/static/public biasanya lebih sederhana dan cukup.
Kapan memilih static dan kapan memilih dynamic?
Secara praktis, aturan sederhananya seperti ini:
- Pilih static jika nilai environment tersedia saat build dan tidak perlu berubah selama artifact hasil build yang sama dijalankan.
- Pilih dynamic jika nilai environment harus dibaca saat runtime dari lingkungan eksekusi saat ini.
- Pilih private untuk data sensitif atau konfigurasi backend internal.
- Pilih public hanya untuk nilai yang memang aman dilihat oleh user di browser.
Contoh situasi umum:
- Static public: URL API frontend seperti
PUBLIC_API_BASE_URL. - Static private: token layanan internal yang dipakai endpoint server.
- Dynamic private: deployment yang menggunakan satu image/container untuk banyak environment dan nilai baru disuntikkan saat runtime.
- Dynamic public: jarang dibutuhkan, tetapi bisa dipakai jika konfigurasi publik ditentukan oleh runtime platform.
Jika Anda tidak punya alasan kuat untuk runtime lookup, biasanya mulai dari static adalah pilihan yang lebih sederhana.
Contoh praktis: API base URL dan public key
1. Menyimpan variabel di .env
PRIVATE_API_BASE_URL=https://internal-api.example.local
PUBLIC_API_BASE_URL=https://api.example.com
PUBLIC_ANALYTICS_KEY=pk_test_abc123
PRIVATE_SERVICE_TOKEN=secret-service-tokenPada contoh ini:
PUBLIC_API_BASE_URLdipakai client untuk request ke API publik.PUBLIC_ANALYTICS_KEYdipakai client untuk inisialisasi library frontend.PRIVATE_API_BASE_URLdanPRIVATE_SERVICE_TOKENdipakai server untuk memanggil service internal yang tidak boleh terekspos.
2. Pemakaian aman di server
Misalnya kita membuat endpoint server di src/routes/api/profile/+server.ts yang meneruskan request ke backend internal.
import { json } from '@sveltejs/kit';
import { PRIVATE_API_BASE_URL, PRIVATE_SERVICE_TOKEN } from '$env/static/private';
export async function GET({ fetch }) {
const response = await fetch(`${PRIVATE_API_BASE_URL}/profile`, {
headers: {
Authorization: `Bearer ${PRIVATE_SERVICE_TOKEN}`
}
});
if (!response.ok) {
return json({ message: 'Gagal mengambil profile' }, { status: response.status });
}
const data = await response.json();
return json(data);
}Kenapa ini aman? Karena token dan private base URL hanya hidup di server. Browser hanya memanggil endpoint SvelteKit Anda, bukan service internal secara langsung. Dengan pola ini, Anda bisa menyembunyikan kredensial sekaligus menerapkan validasi, logging, dan pembatasan akses di server.
3. Pemakaian aman di client
Di sisi client, gunakan hanya variabel publik. Misalnya dalam komponen Svelte:
<script lang="ts">
import { PUBLIC_API_BASE_URL, PUBLIC_ANALYTICS_KEY } from '$env/static/public';
const apiBaseUrl = PUBLIC_API_BASE_URL;
const analyticsKey = PUBLIC_ANALYTICS_KEY;
</script>
<p>API: {apiBaseUrl}</p>
<p>Analytics key: {analyticsKey}</p>Contoh ini aman karena kedua nilai tersebut memang dirancang untuk dapat diketahui oleh browser. Tetapi tetap ingat: public key bukan secret. Jika sebuah layanan memberi Anda secret key, jangan pernah menaruhnya di modul public atau file yang ikut dibundel ke client.
4. Menggunakan dynamic saat runtime dibutuhkan
Jika Anda memang perlu membaca nilai saat runtime, misalnya pada adapter atau deployment tertentu, gunakan:
import { env } from '$env/dynamic/private';
export async function GET() {
const baseUrl = env.PRIVATE_API_BASE_URL;
return new Response(`Using API: ${baseUrl}`);
}Gunakan opsi ini dengan sadar. Dynamic lebih fleksibel, tetapi static biasanya lebih mudah dianalisis dan cenderung lebih jelas saat maintenance.
Pola implementasi yang disarankan
Validasi env di satu tempat
Salah satu masalah yang sering muncul adalah aplikasi gagal di runtime karena ada environment variable yang belum terisi. Praktik yang baik adalah membuat modul konfigurasi server untuk memusatkan validasi.
import { PRIVATE_API_BASE_URL, PRIVATE_SERVICE_TOKEN } from '$env/static/private';
if (!PRIVATE_API_BASE_URL) {
throw new Error('PRIVATE_API_BASE_URL belum diatur');
}
if (!PRIVATE_SERVICE_TOKEN) {
throw new Error('PRIVATE_SERVICE_TOKEN belum diatur');
}
export const serverConfig = {
apiBaseUrl: PRIVATE_API_BASE_URL,
serviceToken: PRIVATE_SERVICE_TOKEN
};Dengan cara ini, kegagalan konfigurasi muncul lebih awal dan lebih mudah didiagnosis.
Pisahkan akses client dan server
Jangan membuat satu file utilitas yang diimpor oleh server dan client jika file itu juga mengakses env privat. Pemisahan modul membantu mencegah impor yang salah.
src/lib/config/public.tsuntuk$env/static/publicsrc/lib/server/config.tsuntuk$env/static/private
Pola ini membuat niat kode lebih jelas dan mengurangi risiko rahasia ikut masuk ke bundle frontend.
Kesalahan umum yang sering terjadi
Menaruh secret pada variabel PUBLIC_
Ini kesalahan paling berbahaya. Semua yang berprefix PUBLIC_ harus dianggap terlihat oleh user akhir. Jangan pernah menyimpan password, private token, secret API key, atau koneksi database dengan prefix ini.
Mengakses env private dari komponen client
Jika Anda mencoba mengimpor $env/static/private dari file yang berjalan di browser, SvelteKit akan mencegahnya. Ini adalah fitur pengaman, bukan keterbatasan yang harus diakali.
Mengandalkan process.env secara langsung di mana-mana
Walau pada konteks tertentu masih mungkin di lingkungan Node tertentu, praktik yang lebih baik di SvelteKit adalah memakai modul $env/*. Alasannya adalah pemisahan public/private menjadi jelas dan perilaku build/runtime lebih konsisten lintas adapter.
Lupa restart dev server setelah mengubah .env
Pada banyak setup, perubahan file .env tidak selalu langsung terbaca. Jika nilai terasa tidak berubah, restart server development terlebih dahulu.
Tips debugging singkat
- Pastikan nama variabel persis sama, termasuk prefix
PUBLIC_. - Jika variabel dipakai di browser, cek apakah memang seharusnya public.
- Jika nilainya
undefined, periksa file.envdan environment deployment. - Tambahkan validasi awal agar aplikasi gagal cepat saat konfigurasi belum lengkap.
- Untuk kasus runtime tertentu, pertimbangkan apakah Anda sebenarnya butuh
dynamicalih-alihstatic.
Catatan keamanan yang perlu diingat
Environment variable membantu memisahkan konfigurasi dari kode, tetapi tidak otomatis membuat aplikasi aman. Keamanan tetap bergantung pada bagaimana Anda menggunakan nilai tersebut.
- Anggap semua variabel
PUBLIC_sebagai data yang bisa dilihat siapa pun. - Simpan secret hanya di sisi server dengan modul private.
- Jangan log secret ke console, monitoring, atau response error.
- Batasi scope token layanan. Jika token bocor, dampaknya harus sekecil mungkin.
- Gunakan endpoint server sebagai perantara saat browser perlu mengakses layanan yang memerlukan secret.
Prinsip praktis: jika sebuah nilai tidak aman ditampilkan di browser developer tools, maka nilai itu tidak boleh berada di
$env/static/publicmaupun$env/dynamic/public.
Penutup
Di SvelteKit, pengelolaan environment variable bukan hanya soal membaca nilai dari .env, tetapi juga soal memilih konteks yang benar: public vs private dan static vs dynamic. Untuk sebagian besar kasus, gunakan $env/static/private untuk secret di server dan $env/static/public untuk konfigurasi yang aman diekspos ke client.
Pilih modul dynamic hanya jika Anda memang membutuhkan lookup saat runtime. Dengan memahami batas ini sejak awal, Anda bisa membuat aplikasi yang lebih rapi, lebih aman, dan lebih mudah dipelihara.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!