D
P
0

Next.js

Next.js 16 Jalan di `localhost` tapi HMR Mati Saat Dibuka Lewat IP LAN? Tambahkan `allowedDevOrigins`

8 Juli 2026·4 menit baca
Next.js 16 Jalan di `localhost` tapi HMR Mati Saat Dibuka Lewat IP LAN? Tambahkan `allowedDevOrigins`

Saya lagi ngerjain sebuah dashboard klien di Next.js 16, dan seperti biasa, begitu layout mulai stabil saya mau lihat langsung di HP. Bukan cuma DevTools mode responsive, tapi perangkat sungguhan di jaringan Wi-Fi yang sama. Jadi saya buka IP LAN mesin saya dari HP, sesuatu seperti http://192.168.1.9:3000, dan halamannya muncul dengan sempurna. Sampai situ, semua terlihat baik-baik saja.

Masalahnya baru terasa begitu saya mulai ngedit. Di laptop, saya ubah satu string di komponen hero, save, dan browser desktop langsung refresh seperti biasa. Tapi HP saya diam saja. Tidak ada perubahan, tidak ada flash, tidak ada apa-apa. Saya save lagi, ganti warna biar jelas, tetap diam. Halaman di HP itu seperti screenshot beku: tampil benar, tapi mati total terhadap perubahan.

Refleks pertama saya, seperti biasa, langsung menuduh yang salah: saya pikir mungkin Wi-Fi-nya lemot, atau HP-nya nge-cache halaman terlalu agresif. Saya hard-refresh, saya bahkan matikan cache dari Safari HP. Masih diam. Baru setelah saya buka console di HP, teka-tekinya kelihatan.

Menemukan jejak yang sebenarnya

Console di HP penuh dengan error cross-origin yang diblokir. Request ke _next/webpack-hmr, endpoint internal yang dipakai Next.js untuk mengirim update hot module reload ke browser, ditolak. Bukan gagal koneksi, bukan timeout. Diblokir secara eksplisit karena alasan origin.

Itu langsung mengubah cara saya memandang masalah ini. Halaman utamanya termuat, jadi server jelas menjawab request dari IP LAN. Tapi koneksi HMR, yang jalan terpisah dan terus-menerus di background, ditolak. Dan yang paling penting: di localhost:3000 semuanya bekerja sempurna. Hanya lewat IP jaringan yang bermasalah. Itu pola yang sangat spesifik, dan begitu saya melihatnya, saya berhenti menyalahkan Wi-Fi dan mulai curiga ini soal konfigurasi.

Kenapa ini terjadi

Next.js 16 menambahkan proteksi cross-origin default untuk dev server. Request ke endpoint internal dev seperti _next/webpack-hmr yang datang dari origin selain localhost akan diblokir kecuali origin itu di-allowlist secara eksplisit. Idenya masuk akal dari sisi keamanan: dev server tidak seharusnya menerima koneksi HMR dari origin sembarangan.

Masalahnya, saat saya buka aplikasi lewat IP jaringan, itu dihitung sebagai origin yang berbeda. http://192.168.1.9:3000 bukan localhost. Jadi halaman HTML-nya boleh dimuat, tapi koneksi HMR yang datang dari origin IP itu langsung ditolak. Bukan bug, bukan Wi-Fi, bukan cache. Ini perilaku default yang memang disengaja, dan saya cuma kena karena cara saya mengetes, dari HP lewat IP, memang origin yang belum dikenali.

Begitu logikanya klik, semuanya masuk akal. localhost jalan karena itu origin yang secara implisit dipercaya. IP LAN tidak jalan karena dia origin asing yang belum saya izinkan. Tidak ada yang rusak. Yang salah cuma asumsi saya bahwa kalau halaman termuat, berarti dev server sudah menerima semua koneksi dari origin itu.

Perbaikannya

Solusinya bukan menurunkan versi Next.js atau mematikan proteksinya. Solusinya adalah memberi tahu dev server bahwa origin jaringan itu memang saya percaya. Next.js menyediakan opsi allowedDevOrigins di file config persis untuk ini.

Saya tambahkan origin jaringan ke next.config:

// next.config.js
const nextConfig = {
  allowedDevOrigins: ['192.168.1.9', 'http://192.168.1.9:3000'],
}
 
module.exports = nextConfig

Restart dev server, buka lagi dari HP lewat IP yang sama, dan sekarang HMR jalan persis seperti di desktop. Save di laptop, HP langsung ikut refresh. Request ke _next/webpack-hmr tidak lagi diblokir karena origin-nya sudah masuk allowlist.

Saya masukkan bentuk hostname polos maupun URL lengkap dengan port karena, tergantung setup, salah satunya bisa lebih cocok dengan origin yang benar-benar dikirim browser. Memasukkan keduanya menutup celah tanpa saya harus menebak-nebak format mana yang dipakai Next.js untuk mencocokkan.

Kalau IP mesin kamu berubah-ubah, misalnya DHCP kasih alamat berbeda tiap hari, kamu perlu update daftar ini saat itu terjadi. Untuk workflow yang lebih stabil, saya biasanya pin IP lokal mesin lewat reservasi DHCP di router, jadi origin di allowedDevOrigins tetap valid dari hari ke hari.

Pelajaran

Kalau di Next.js 16 aplikasi jalan sempurna di localhost tapi hot reload diam saat dibuka lewat IP LAN, jangan buru-buru menyalahkan Wi-Fi atau cache HP. Buka console di perangkat itu dulu, dan cek apakah ada request ke _next/webpack-hmr yang diblokir cross-origin. Kalau iya, itu proteksi cross-origin default Next.js 16 yang sedang bekerja, dan solusinya cukup satu baris: tambahkan origin jaringan ke allowedDevOrigins di next.config. Perlakukan celah "jalan-di-localhost-tapi-tidak-di-jaringan" sebagai bug config yang nyata, bukan sekadar kuirk dev-env. Sejak itu, langkah pertama saya saat HP diam bukan lagi hard-refresh, tapi bertanya dulu: origin mana yang sedang saya pakai, dan apakah dev server memang mengenalinya?