diff --git a/paperless-frontend/src/App.tsx b/paperless-frontend/src/App.tsx
index 755e4ee..390f870 100644
--- a/paperless-frontend/src/App.tsx
+++ b/paperless-frontend/src/App.tsx
@@ -7,6 +7,7 @@ import { saveReturnUrl } from './auth/sessionRedirect';
import { ThemeProvider, useTheme } from './theme/ThemeContext';
import AuthCallback from './auth/AuthCallback';
import AppLayout from './layouts/AppLayout';
+import AppErrorBoundary from './components/AppErrorBoundary';
import { Spin, Result, Button } from 'antd';
import type { ReactNode } from 'react';
@@ -117,6 +118,7 @@ function ThemedApp() {
+
}>
} />
@@ -143,6 +145,7 @@ function ThemedApp() {
+
diff --git a/paperless-frontend/src/components/AppErrorBoundary.tsx b/paperless-frontend/src/components/AppErrorBoundary.tsx
new file mode 100644
index 0000000..020de22
--- /dev/null
+++ b/paperless-frontend/src/components/AppErrorBoundary.tsx
@@ -0,0 +1,62 @@
+import { Component } from 'react';
+import type { ReactNode } from 'react';
+import { Button, Result } from 'antd';
+
+interface Props {
+ children: ReactNode;
+}
+
+interface State {
+ error: Error | null;
+}
+
+// Erkennt fehlgeschlagene Lazy-Chunk-Imports:
+// Safari: "Importing a module script failed."
+// Chrome: "Failed to fetch dynamically imported module: …"
+// Firefox: "error loading dynamically imported module"
+function istChunkLadefehler(error: Error): boolean {
+ return /module script failed|dynamically imported module/i.test(error.message);
+}
+
+/**
+ * Fängt Renderfehler ab, die sonst den kompletten React-Baum aushängen und
+ * nur eine weiße Seite hinterlassen — insbesondere fehlgeschlagene
+ * React.lazy-Chunk-Imports nach einem Deployment oder bei beschädigtem
+ * Browser-Cache (Assets werden mit "immutable" gecacht und nie revalidiert).
+ */
+export default class AppErrorBoundary extends Component {
+ state: State = { error: null };
+
+ static getDerivedStateFromError(error: Error): State {
+ return { error };
+ }
+
+ componentDidCatch(error: Error) {
+ console.error('AppErrorBoundary:', error);
+ }
+
+ render() {
+ const { error } = this.state;
+ if (!error) return this.props.children;
+
+ return (
+ window.location.reload()}>
+ Seite neu laden
+
+ }
+ />
+ );
+ }
+}
diff --git a/paperless-frontend/src/main.tsx b/paperless-frontend/src/main.tsx
index dfacde0..3a82059 100644
--- a/paperless-frontend/src/main.tsx
+++ b/paperless-frontend/src/main.tsx
@@ -3,6 +3,22 @@ import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';
+// Nach einem Deployment existieren die alten, inhalts-gehashten Chunks nicht
+// mehr; zudem bleibt ein einmal fehlerhaft zwischengespeicherter Chunk wegen
+// "Cache-Control: immutable" dauerhaft defekt. Vite meldet fehlgeschlagene
+// dynamische Imports als 'vite:preloadError' — dann automatisch neu laden,
+// damit der Browser die aktuelle index.html samt gültiger Chunk-Namen holt.
+// Höchstens ein Versuch pro Minute, sonst droht eine Reload-Schleife; danach
+// zeigt der AppErrorBoundary eine sichtbare Fehlermeldung.
+window.addEventListener('vite:preloadError', (event) => {
+ const KEY = 'vite-preload-error-reload';
+ const letzterVersuch = Number(sessionStorage.getItem(KEY) ?? 0);
+ if (Date.now() - letzterVersuch < 60_000) return;
+ sessionStorage.setItem(KEY, String(Date.now()));
+ event.preventDefault();
+ window.location.reload();
+});
+
createRoot(document.getElementById('root')!).render(