diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx
index 3204db83..e0987d66 100644
--- a/app/[locale]/layout.tsx
+++ b/app/[locale]/layout.tsx
@@ -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({
/>
+
diff --git a/components/chunk-load-error-handler.tsx b/components/chunk-load-error-handler.tsx
new file mode 100644
index 00000000..a072da1b
--- /dev/null
+++ b/components/chunk-load-error-handler.tsx
@@ -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;
+}
+
diff --git a/docs/CHUNK_LOAD_ERROR_HANDLER.md b/docs/CHUNK_LOAD_ERROR_HANDLER.md
new file mode 100644
index 00000000..041b045c
--- /dev/null
+++ b/docs/CHUNK_LOAD_ERROR_HANDLER.md
@@ -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
+