React 404 Seite: 5 Fehlerseiten für den Next.js App Router

Die meisten Vorlagen für eine React 404 Seite bestehen aus einer großen Zahl, einer traurigen Illustration und einem Button „Go home“. Damit ist einer der fünf Fehler-Screens abgedeckt, auf die eine echte App trifft, und den Statuscode überlässt sie dem, was der Server gerade schickt. Dieses Tutorial baut eine React 404 Seite, die Leuten hilft, ans Ziel zu kommen, und danach die vier Screens daneben: eine 500-Seite mit Retry, eine Wartungsseite mit Countdown, eine Offline-Seite für deine PWA und eine Seite für fehlenden Zugriff, über die man Zugriff anfragen kann. Alles wird im Next.js App Router verdrahtet, mit den Dateikonventionen von Next.js 16.3. Wir bauen Wingo UI, und der Code nutzt unseren Block Error Pages. Wir sind also nicht neutral; die Verdrahtung funktioniert mit jeder Komponente.
Was sollte eine React 404 Seite leisten?
Sie bringt die Person auf eine funktionierende Seite und hält die tote URL aus der Suche heraus. Vier Dinge entscheiden, ob jemand den Weg zurückfindet:
- Sag in klaren Worten, was passiert ist. „Diese Seite gibt es nicht oder sie wurde verschoben“, nicht „Error 404“.
- Biete den nächsten Schritt an. Ein Suchfeld, die drei oder vier Seiten, die Leute am häufigsten suchen, und einen Weg zurück dorthin, wo sie herkamen.
- Liefere den richtigen Status. Google markiert eine Seite, die mit 200 antwortet, aber eine Fehlermeldung zeigt, in der Search Console als Soft 404 (opens in a new tab). Die Not-found-Oberfläche braucht einen 404, oder zumindest ein
noindex. - Setz den Fokus nach einer clientseitigen Navigation auf den Titel, damit jemand mit Screenreader hört, dass sich die Seite geändert hat. Beim ersten Laden lässt du das, denn da beginnt der Browser ohnehin oben. Der Error Pages Block hält sich über seinen Prop
autoFocusTitlean diese Regel (standardmäßig an).
Dieselbe Checkliste gilt für die anderen vier Fehler-Screens, jeweils mit einem anderen nächsten Schritt.
Welche Fehlerseiten braucht eine Next.js App?
Fünf: nicht gefunden, Serverfehler, Wartung, offline und kein Zugriff. Jede hat ihren eigenen Einstiegspunkt im App Router:
Die Fakten in dieser Tabelle stammen aus der Doku von Next.js 16.3, die in node_modules/next/dist/docs mitkommt, gelesen am 16. Oktober 2026. forbidden.tsx und useOffline sind dort noch experimentell.
Wie installiere ich eine Vorlage für eine React 404 Seite?
Installier den Error Pages Block mit der CLI:
Das kopiert components/blocks/error-pages.tsx mit seiner Datendatei und den Teilen, aus denen er besteht (Alert, Countdown, Tracker, Dialog, Suchfeld und ein paar mehr), dazu die npm-Pakete, die sie brauchen, darunter motion, lucide-react, react-hook-form und zod. Error Pages gehört zu Wingo UI Pro.
Die Standardwerte des Blocks sind Demo-Inhalte: ein Acme-CRM-Logo, support@acme.com, Beispiel-Admins, ein Beispiel-Stacktrace. Gib einmal deine eigenen mit, in einem kleinen Client-Wrapper, der ihm auch den Link von Next.js übergibt:
statusHref="" blendet die Links zur Statusseite aus, bis du eine hast. Server-Dateien wie not-found.tsx können diesen Wrapper direkt rendern, solange jeder Prop, den sie übergeben, reine Daten, JSX (Icons gehen) oder eine Server Action ist. Funktionen, die in einer Server-Datei definiert sind, lassen sich nicht an den Client-Wrapper übergeben.
Wie baue ich eine Next.js 404 Seite?
Leg app/not-found.tsx an. Diese Datei ist die Next.js not found page: Sie rendert für jede URL, zu der keine Route passt, und für jedes Segment, das notFound() aufruft:
Das Suchfeld navigiert standardmäßig mit Enter zu /search?q=. Übergib onSearch aus einer Client-Komponente, um woandershin zu leiten, oder showSearch={false}, wenn du keine Suche hast. „Go back“ nutzt history.back(), wenn es einen Verlauf gibt, und fällt auf den Link zur Startseite zurück, wenn der Tab keinen Verlauf hat, etwa weil der Link in einem neuen Tab geöffnet wurde.
$ npx wingo-ui@latest add error-pagesFür einen fehlenden Datensatz rufst du notFound() in der Seite auf, die ihn lädt:
Zwei Details zum Status, die die Doku ausdrücklich nennt. notFound() liefert einen 404, solange die Antwort noch nicht gestreamt wird. Hat eine loading.tsx-Boundary die Shell schon gesendet, bleibt der Status 200, und Next.js fügt stattdessen <meta name="robots" content="noindex"> ein. Brauchst du den echten 404 für deine Analytics, prüf, ob der Datensatz existiert, bevor irgendetwas gestreamt wird. Und wenn eine App mehrere Root-Layouts hat, gibt dir das experimentelle global-not-found.tsx (hinter experimental.globalNotFound) einen einzigen 404, der ganz ohne Layout rendert.
Wann ist eine komplette 404-Seite zu viel?
Wenn die URL stimmt und nur die Daten leer sind. Eine Suche ohne Treffer, eine gefilterte Tabelle mit null Zeilen oder ein neues Konto ohne Rechnungen sollten mit 200 und einem Empty State innerhalb der Seite antworten, nie mit einem 404. Der kostenlose Empty State deckt diesen Fall mit seinen Presets no-results, empty, no-permission und offline ab, und live kündigt ihn Screenreadern an, wenn sich die Ergebnisse ändern:
Wie zeige ich eine 500-Seite mit Retry?
Leg app/error.tsx an und verbinde seinen Prop retry mit dem Button „Try again“. Die Datei packt jedes Segment in eine React Error Boundary, also muss sie eine Client-Komponente sein. Seit Next.js 16.3 ist der Prop retry stabil. Er lädt die Daten des Segments neu und rendert es neu, anders als das ältere reset(), das nur neu rendert, ohne neu zu laden. Ein Segment, dessen Datenabruf fehlschlug, zeigt mit reset() also wieder denselben Fehler:
error.digest ist der Hash, den Next.js auch ins Server-Log schreibt. Damit eignet er sich gut als ID, die Leute dem Support nennen können: Der Block kopiert ihn mit einem Klick. Fehler, die im Browser geworfen werden, haben keinen Digest, und errorId="" blendet die Zeile mit der ID aus. In Produktion kommen Fehler aus Server Components mit einer generischen Meldung beim Client an, und den Stacktrace brauchen Besucher ohnehin nicht. Deshalb erscheinen die technischen Details hier nur in der Entwicklungsumgebung.
$ npx wingo-ui@latest add error-pageserror.tsx fängt keine Fehler im Root-Layout ab. Dafür ergänzt du app/global-error.tsx. Diese Datei ersetzt das ganze Dokument, rendert also ihr eigenes <html> und <body> und importiert deine Styles:
Sie liegt außerdem außerhalb jedes Theme-Providers. Ein klassenbasierter Dark Mode erreicht sie also nicht: Diese Seite rendert mit deinen hellen Tokens, solange du die Klasse nicht selbst setzt.
Innerhalb einer App-Shell übergibst du layout="inline" an eine beliebige Variante, zum Beispiel aus einem verschachtelten app/(app)/error.tsx. Die Seite lässt dann ihr eigenes Logo und ihren Footer weg und füllt den Hauptbereich der Shell. Scheitert ein Bericht, bleibt die Sidebar deiner Admin Shell also drumherum stehen.
Wie baue ich eine React Wartungsseite?
Liefer sie mit einem 503-Status aus und sag den Leuten, wann sie endet. Eine typische React Wartungsseite ist ein statisches „Wir sind bald zurück“, das mit 200 antwortet, und macht damit beides falsch. Googles Doku zu HTTP-Statuscodes (opens in a new tab) (aktualisiert am 4. Februar 2026) beschreibt, dass 5xx-Antworten die Crawler bremsen, dass Inhalte von diesen URLs ignoriert werden und dass indexierte URLs zunächst erhalten bleiben und erst verschwinden, wenn die Fehler anhalten. Eine Wartungsseite mit 200 bekommt keinen dieser Schutzmechanismen.
Die Seite selbst ist eine ganz normale Route:
until steuert einen live laufenden Countdown. Erreicht er null, meldet die Seite, dass die Wartung vorbei ist, und der Haupt-Button wird zu „Reload“. Dabei gibt es zwei Fallstricke. Ohne connection() wird die Seite vorgerendert und behält den Wert, den MAINTENANCE_UNTIL beim Build hatte. Und fehlt die Variable, fällt until auf das Beispieldatum des Blocks zurück, das in der Vergangenheit liegt. Die Seite öffnet dann mit „Maintenance is over“. showStatus und showSubscribe sind aus, weil ihre Standardwerte Beispieldaten sind: Schalte sie ein, sobald du deine eigene statusHistory (ein Tracker über 30 Tage) und eine Server Action für onSubscribe übergibst. Für eine vollständige öffentliche Uptime-Seite ist die Vorlage Status Page der separate Screen, auf den statusHref zeigen sollte.
Um jede Anfrage dorthin zu schicken, nimm proxy.ts (die Datei, die in Next.js 16 middleware.ts ersetzt hat). Verlass dich für den Status nicht auf NextResponse.rewrite(): Im Router von 16.3 reicht ein Rewrite die Header des Proxys weiter, aber die Zielseite rendert die Antwort, und eine normale Seite antwortet mit 200. Für einen echten 503 holst du die gerenderte Seite per fetch und gibst sie mit deinem eigenen Status zurück:
Halt /maintenance aus dem Matcher heraus, sonst ruft der fetch wieder den Proxy auf. Retry-After nimmt Sekunden oder ein HTTP-Datum; setz es auf das Ende des Wartungsfensters. Clientseitige Navigationen bekommen dasselbe HTML mit einem 503, also weicht der Router auf ein vollständiges Neuladen der Seite aus, und genau das willst du während der Wartung.
Wie bekommt meine PWA eine Offline-Seite?
Leg eine /offline-Route in einem Service Worker in den Cache und liefere sie aus, wenn das Laden einer Seite fehlschlägt. Das deckt vollständige Seitenaufrufe ab; Anfragen in einer App, die schon offen ist, brauchen eine andere Lösung.
Innerhalb der App scheitert eine Soft Navigation, ein Prefetch oder eine Server Action, weil das Netz weg ist. Next.js 16.3 hat dafür eine experimentelle Antwort: Mit experimental.useOffline werden diese Anfragen wiederholt, sobald die Verbindung zurück ist, und der Hook useOffline() aus next/offline liefert true, damit eine Komponente ein Banner zeigen kann. Ohne das Flag liefert der Hook immer false. Eine Fehlerseite braucht es dafür nicht.
Ein vollständiger Seitenaufruf ohne Netz. Der Browser hat kein HTML, das er zeigen könnte, also hilft nur ein Service Worker. Leg bei seiner Installation eine Offline-Route in den Cache und liefere sie aus, wenn eine Navigation scheitert:
Registrier ihn einmal aus einer Client-Komponente im Root-Layout:
Die Offline-Route prüft die Verbindung nach ihrem eigenen Zeitplan. Die HEAD-Anfrage ist keine Navigation, also lässt der Service Worker sie zum Netz durch:
Render <OfflineView /> aus app/offline/page.tsx. Das ist die PWA Offline Seite, die Leute nach einem Neuladen ohne Empfang sehen, weiterhin unter der URL, die sie aufgerufen haben. Sie prüft alle 10 Sekunden erneut und zeigt dabei einen Fortschrittsbalken. Löst der Browser online aus, prüft sie sofort, und sobald eine Prüfung klappt, lädt sie die ursprüngliche URL neu. offlinePages={[]} blendet die Liste „saved on this device“ aus, bis du wirklich Seiten cachst.
Einen Haken hat der minimale Worker oben: Er cacht nur das HTML von /offline. Die CSS- und JavaScript-Chunks unter /_next/static liegen nicht im Cache, also erscheint die Seite ohne Netz ungestylt, und die Retry-Schleife startet nie. Leg diese Dateien ebenfalls vorab in den Cache. Serwist (opens in a new tab), die Option, auf die der PWA-Guide von Next.js verweist, baut diese Precache-Liste aus deinem Build-Output. Wenn du die App zu einer PWA machst, kümmert sich unser Beitrag zum React PWA Install Prompt um die Installation.
Wie zeige ich eine Seite für fehlenden Zugriff an?
Liefer einen 403, der sagt, wer Zugriff gewähren kann. Für eine angemeldete Person ohne die passende Rolle verschleiert ein 404, dass es die Seite gibt, und eine Weiterleitung zur Anmeldung endet in einer Schleife. Schalte experimental.authInterrupts in next.config.ts ein, ruf forbidden() aus next/navigation dort auf, wo du die Rolle prüfst (Next.js ergänzt bei dieser Antwort ein noindex-Tag), und leg app/forbidden.tsx an. Der Status funktioniert wie bei notFound(): Einen echten 403 bekommst du nur, wenn die Prüfung läuft, bevor das Streaming der Antwort beginnt.
getSession, getWorkspaceAdmins und die beiden Server Actions schreibst du selbst. requestAccess bekommt { adminId, reason }. Ein abgelehntes Promise zeigt seine Meldung im Dialog, der sich auf Smartphones als Bottom Sheet öffnet. Ein Fallstrick in Produktion: Next.js ersetzt die Meldung eines Fehlers, der in einer Server Action geworfen wird, durch eine generische. „Du hast schon eine offene Anfrage“ würde den Dialog also nicht erreichen. Lass die Action stattdessen { error } zurückgeben und übergib onRequestAccess aus einer kleinen Client-Komponente, die sie aufruft und new Error(result.error) wirft. Nach einer erfolgreichen Anfrage wird der Button zu einem deaktivierten „Request sent“ mit der Uhrzeit.
$ npx wingo-ui@latest add error-pagesWie sieht das fertige Setup aus?
Sechs Routendateien, ein Proxy, ein Service Worker und ein Wrapper um einen Block:
Die passende Shell für die Inline-Varianten baut unser Tutorial zum Next.js Admin Dashboard, und weitere komplette Screens findest du in der Kategorie Praxis: Screens und Apps.
Fang mit dem kostenlosen Empty State für Sackgassen innerhalb einer Seite an, und nimm den Block Error Pages dazu, wenn du alle fünf vollständigen Screens willst: npx wingo-ui@latest add error-pages.
Häufige Fragen
Wie erstelle ich eine 404-Seite im Next.js App Router?
Leg app/not-found.tsx an. Die Datei rendert für jede URL ohne passende Route und immer dann, wenn eine Server Component notFound() aus next/navigation aufruft, und Next.js ergänzt automatisch ein noindex-Meta-Tag.
Liefert die Next.js not found page einen 404-Statuscode?
Sie liefert 404, wenn die Antwort nicht gestreamt wird. Hat eine loading.tsx-Boundary das Streaming schon gestartet, bevor notFound() lief, bleibt der Status 200, aber Next.js fügt ein noindex-Meta-Tag ein, damit die URL trotzdem nicht im Index landet.
Wie baue ich eine 404-Seite mit React Router?
Leg eine Catch-all-Route mit path="*" an, die deine Not-found-Komponente rendert. In einer Single Page App antwortet der Server trotzdem für jeden Pfad mit 200, also stell den Host so ein, dass er für Pfade außerhalb deiner Routenliste 404 liefert, wenn dir Suchtraffic wichtig ist.
Welchen Statuscode sollte eine Wartungsseite liefern?
503 Service Unavailable, mit einem Retry-After-Header, der sagt, wann es weitergeht. Google dokumentiert, dass 5xx-Antworten seine Crawler bremsen, ihr Inhalt verworfen wird und indexierte URLs zunächst erhalten bleiben; eine Wartungsseite mit 200 bekommt keinen dieser Schutzmechanismen.
Wie zeige ich in einer PWA eine Offline-Seite an?
Leg beim Installieren des Service Workers eine /offline-Route in den Cache und liefere sie aus, wenn eine Navigation fehlschlägt. Für eine App, die schon offen ist, wiederholt die experimentelle Option useOffline in Next.js 16.3 fehlgeschlagene Navigationen, Prefetches und Server Actions, sobald die Verbindung wieder da ist, und der Hook useOffline aus next/offline meldet den Zustand.
- Fehlerseiten
- Next.js
- App Router
- PWA
- React


