update bug fixing
This commit is contained in:
parent
d10bd92960
commit
b7679cbcb1
|
|
@ -19,6 +19,7 @@ import { NextIntlClientProvider } from "next-intl";
|
|||
import { getMessages } from "next-intl/server";
|
||||
import DirectionProvider from "@/providers/direction-provider";
|
||||
import AuthProvider from "@/providers/auth.provider";
|
||||
import ChunkLoadErrorHandler from "@/components/chunk-load-error-handler";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Media Hub | POLRI",
|
||||
|
|
@ -96,6 +97,7 @@ export default async function RootLayout({
|
|||
/>
|
||||
</head>
|
||||
<body className={`${inter.className} dashcode-app`}>
|
||||
<ChunkLoadErrorHandler />
|
||||
<NextIntlClientProvider messages={messages} locale={locale}>
|
||||
<AuthProvider>
|
||||
<ThemeProvider attribute="class" defaultTheme="light">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
/**
|
||||
* Component to handle ChunkLoadError automatically
|
||||
* When a chunk fails to load (usually after deployment),
|
||||
* this component will force refresh the page once
|
||||
*/
|
||||
export default function ChunkLoadErrorHandler() {
|
||||
useEffect(() => {
|
||||
// Key to track if we've already refreshed for this error
|
||||
const REFRESH_KEY = "chunk-load-error-refreshed";
|
||||
|
||||
// Handle unhandled promise rejections (for dynamic imports)
|
||||
const handlePromiseRejection = (event: PromiseRejectionEvent) => {
|
||||
const error = event.reason;
|
||||
|
||||
// Check if it's a ChunkLoadError
|
||||
if (
|
||||
error?.name === "ChunkLoadError" ||
|
||||
error?.message?.includes("Loading chunk") ||
|
||||
error?.message?.includes("ChunkLoadError") ||
|
||||
error?.message?.includes("Failed to fetch dynamically imported module") ||
|
||||
error?.message?.includes("failed to load resource")
|
||||
) {
|
||||
handleChunkLoadError();
|
||||
}
|
||||
};
|
||||
|
||||
// Handle regular errors
|
||||
const handleError = (event: ErrorEvent) => {
|
||||
const error = event.error;
|
||||
|
||||
// Check if it's a ChunkLoadError
|
||||
if (
|
||||
error?.name === "ChunkLoadError" ||
|
||||
event.message?.includes("Loading chunk") ||
|
||||
event.message?.includes("ChunkLoadError") ||
|
||||
event.message?.includes("Failed to fetch dynamically imported module")
|
||||
) {
|
||||
handleChunkLoadError();
|
||||
}
|
||||
};
|
||||
|
||||
const handleChunkLoadError = () => {
|
||||
// Check if we've already refreshed
|
||||
const hasRefreshed = sessionStorage.getItem(REFRESH_KEY);
|
||||
|
||||
if (!hasRefreshed) {
|
||||
console.log("ChunkLoadError detected. Refreshing page...");
|
||||
|
||||
// Mark that we've refreshed
|
||||
sessionStorage.setItem(REFRESH_KEY, "true");
|
||||
|
||||
// Force reload the page (bypassing cache)
|
||||
window.location.reload();
|
||||
} else {
|
||||
console.error("ChunkLoadError persists after refresh. There might be a deeper issue.");
|
||||
|
||||
// Clear the flag after 30 seconds in case user navigates away and comes back
|
||||
setTimeout(() => {
|
||||
sessionStorage.removeItem(REFRESH_KEY);
|
||||
}, 30000);
|
||||
}
|
||||
};
|
||||
|
||||
// Add event listeners
|
||||
window.addEventListener("error", handleError);
|
||||
window.addEventListener("unhandledrejection", handlePromiseRejection);
|
||||
|
||||
// Cleanup event listeners
|
||||
return () => {
|
||||
window.removeEventListener("error", handleError);
|
||||
window.removeEventListener("unhandledrejection", handlePromiseRejection);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// This component doesn't render anything
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# 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:
|
||||
1. Mendeteksi ChunkLoadError secara otomatis
|
||||
2. Melakukan force refresh **hanya sekali** untuk mencegah infinite reload loop
|
||||
3. Menggunakan `sessionStorage` untuk tracking refresh state
|
||||
|
||||
## Implementation
|
||||
|
||||
### 1. Component: `chunk-load-error-handler.tsx`
|
||||
Component client-side yang mendengarkan error events:
|
||||
- `window.error` - untuk menangkap error reguler
|
||||
- `window.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
|
||||
↓
|
||||
Check sessionStorage
|
||||
↓
|
||||
No refresh yet? → Yes → Set flag & Reload
|
||||
↓
|
||||
Already refreshed? → Show error in console
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
## Testing
|
||||
Untuk test handler ini:
|
||||
1. Build aplikasi: `npm run build`
|
||||
2. Start production: `npm run start`
|
||||
3. Buka aplikasi di browser
|
||||
4. Build ulang aplikasi (tanpa menutup browser)
|
||||
5. Navigate ke halaman yang menggunakan dynamic imports
|
||||
6. 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
|
||||
|
||||
## Notes
|
||||
- SessionStorage akan di-clear otomatis setelah 30 detik jika error persists
|
||||
- Handler tidak render apapun (return null)
|
||||
- Zero impact pada performance
|
||||
- Compatible dengan semua browser modern
|
||||
|
||||
Loading…
Reference in New Issue