5.0 KiB
Chunk Load Error Handler
Problem
ChunkLoadError terjadi ketika aplikasi Next.js mencoba memuat chunk JavaScript yang tidak lagi tersedia, biasanya terjadi karena:
- Deployment baru sementara user masih membuka halaman lama
- File chunk sudah berubah atau dihapus
- Network issues
- Cache issues
Error ini menyebabkan tampilan web bermasalah dan user tidak bisa menggunakan fitur tertentu.
Solution
Implementasi automatic force refresh yang akan:
- Mendeteksi ChunkLoadError secara otomatis
- Melakukan force refresh hanya sekali untuk mencegah infinite reload loop
- Menggunakan
sessionStorageuntuk tracking refresh state
Implementation
1. Component: chunk-load-error-handler.tsx
Component client-side yang mendengarkan error events:
window.error- untuk menangkap error regulerwindow.unhandledrejection- untuk menangkap promise rejections dari dynamic imports
Component ini akan:
- Mendeteksi berbagai variasi ChunkLoadError
- Check apakah sudah pernah refresh (via sessionStorage)
- Jika belum, lakukan
window.location.reload()untuk force refresh - Jika sudah refresh tapi masih error, tidak akan refresh lagi (mencegah infinite loop)
2. Integration di Root Layout
Component ditambahkan di root layout (app/[locale]/layout.tsx) agar berfungsi di seluruh aplikasi.
How It Works
User opens app → Deployment happens → User navigates → ChunkLoadError occurs
↓
Handler detects error
↓
Validate it's actual ChunkLoadError
(not API error or normal network error)
↓
Check sessionStorage
↓
No refresh yet? → Yes → Set flag & Reload (100ms delay)
↓
Already refreshed? → Show error in console
Error Detection Logic
Handler hanya mendeteksi ChunkLoadError yang spesifik:
- Error name adalah "ChunkLoadError"
- Error message mengandung "Loading chunk" atau "ChunkLoadError"
- Error terkait
_next/staticatau_next(Next.js chunks) - Mengecualikan error API, HTTP requests, atau service calls
Ini mencegah false positive dari Promise rejection biasa.
Benefits
✅ User experience lebih baik - no more broken page
✅ Automatic recovery dari ChunkLoadError
✅ Aman - hanya refresh sekali, tidak ada infinite loop
✅ Bekerja di background tanpa mengganggu user
✅ Works untuk semua tipe lazy-loaded components
✅ Tidak konflik dengan Promise rejection biasa (API calls, etc)
✅ Prevention untuk multiple simultaneous refresh
✅ Time-based protection (tidak refresh jika < 5 detik dari refresh terakhir)
Testing
Untuk test handler ini:
- Build aplikasi:
npm run build - Start production:
npm run start - Buka aplikasi di browser
- Build ulang aplikasi (tanpa menutup browser)
- Navigate ke halaman yang menggunakan dynamic imports
- Handler akan otomatis refresh jika terjadi ChunkLoadError
Monitoring
Check browser console untuk melihat log:
"ChunkLoadError detected. Refreshing page..."- saat refresh pertama kali"ChunkLoadError persists after refresh..."- jika masih error setelah refresh
Promise Handling & Best Practices
Mencegah Konflik dengan Promise
Handler telah dioptimasi untuk tidak konflik dengan Promise yang sedang berjalan:
-
Spesifik Error Detection: Hanya mendeteksi ChunkLoadError yang benar-benar terkait Next.js chunks (
_next/static,_next/), tidak menangkap API errors atau network errors biasa. -
Component Cleanup: Komponen yang menggunakan async initialization (seperti
spit-convert-form.tsx) harus menggunakan cleanup pattern:
useEffect(() => {
let isMounted = true;
const init = async () => {
if (isMounted) {
await initializeComponent();
}
};
init();
return () => {
isMounted = false;
};
}, []);
- AbortError Handling: Catch block harus mengecualikan AbortError:
catch (error: any) {
// Skip error alert for AbortError (navigation/refresh)
if (error?.name === 'AbortError' || error?.message?.includes('abort')) {
return;
}
// Handle other errors...
}
Time-Based Protection
- Handler tidak akan refresh jika refresh terakhir < 5 detik yang lalu
- Flags akan di-clear otomatis setelah 5 menit untuk session baru
- Delay 100ms sebelum reload untuk mencegah immediate re-trigger
Notes
- SessionStorage akan di-clear otomatis setelah 1 menit jika error persists
- Handler tidak render apapun (return null)
- Zero impact pada performance
- Compatible dengan semua browser modern
- Event listeners menggunakan capture phase untuk prioritas lebih tinggi