Start / Seminare / React v19 Grundlagen & Moderne Features
Modul
React v19 - Routing & Navigation
4 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
React v19+ — Routing & Navigation
0:00 Die Adresszeile im Browser ist eine Errungenschaft, die wir völlig für selbstverständlich halten. Sie erlaubt, eine Seite zu verschicken, sie zu einem Lesezeichen zu machen, per Zurück-Taste einen Schritt zu gehen. Genau das geht in einer Single-Page-Anwendung verloren, wenn man sich nicht darum kümmert — dann gibt es nur noch eine einzige Adresse für alles.
0:20 Routing holt diese Errungenschaft zurück: Jede Ansicht bekommt ihre eigene URL. Heute schauen wir uns an, wie man einen Routenbaum aufbaut, ihn schnell hält, absichert und dafür sorgt, dass auch Suchmaschinen etwas davon haben.
Routing & Navigation in React v19+
0:33 Der Weg führt von der ersten Route bis zur crawlbaren Navigation. Wir starten mit React Router in Version 7 und dem Routenbaum samt gemeinsamen Layouts. Danach geht es um Geschwindigkeit — jede Route bekommt ihr eigenes Paket, das erst bei Bedarf lädt. Im dritten Kapitel sichern wir Bereiche ab, die nicht jeder sehen soll.
0:53 Und zum Schluss das Thema, das in SPAs traditionell schwierig ist: Suchmaschinen. Vier Kapitel, jedes mit einer eigenen Übung. Kurz zu Ihnen. Routing ist ein Feld, auf dem es erstaunlich viele Lösungen gibt — React Router in verschiedenen Generationen, TanStack Router, das eingebaute Routing von Next.js, manchmal auch etwas Selbstgebautes.
1:14 Was davon setzen Sie ein? Und die zweite Frage zielt auf die Stellen, an denen es typischerweise wehtut: geschützte Bereiche, bei denen der Nutzer nach dem Login auf der Startseite landet statt am gewünschten Ziel — oder SEO, wo eine schöne Anwendung bei Google schlicht nicht auftaucht. Sagen Sie mir gern, was heute konkret sitzen soll.
React Router 7+ & Nested Routes
1:34 Beginnen wir mit dem Fundament: dem Routenbaum. React Router ist hier der De-facto-Standard, und Version 7 hat den Ansatz noch einmal spürbar verschoben. Was sich geändert hat und warum verschachtelte Routen so praktisch sind, klären wir jetzt. Im Kern ist Routing eine Abbildung: Diese Adresse zeigt jene Komponente. Ab Version 7 beschreiben Sie diese Zuordnung als Datenstruktur — ein Objekt, das den ganzen Baum enthält, statt Routen im Markup zu verteilen.
2:02 Der Vorteil zeigt sich beim Verschachteln. Denken Sie an ein Bürogebäude: Der Eingangsbereich mit Empfang und Wegweiser bleibt immer gleich, nur der Raum dahinter wechselt. Genau das leistet das `<Outlet />` — es markiert im Layout die Stelle, an der die jeweilige Kindroute erscheint. Sie schreiben Navigation und Rahmen einmal, und alle Unterseiten erben sie.
2:25 Der erste Punkt ist der eigentliche Gewinn: Die URL wird zu einem Stück Zustand — und zwar zu dem ehrlichsten, den Sie haben. Sie ist teilbar, man kann sie verschicken, der Zurück-Button funktioniert wieder wie erwartet. Nested Routes ersparen Ihnen, dieselbe Navigation in zehn Komponenten zu wiederholen. Deep-Linking bedeutet, dass jemand direkt auf einer Unterseite einsteigen kann, statt sich von der Startseite durchzuklicken.
2:50 Und der vierte Punkt ist die Neuerung von Version 7: Der Data-Router lädt die Daten einer Route, bevor gerendert wird — nicht mehr hinterher im Effekt. Das erspart das übliche Spinner-Flackern. Der Aufbau ist geradlinig. Nach der Installation beschreiben Sie den Baum mit `createBrowserRouter` — einer Liste von Objekten, jedes mit Pfad und Element.
3:10 Der `RouterProvider` montiert das Ganze in Ihrer Anwendung, und ab da hört React Router auf die Adresszeile. Unterseiten kommen als `children` in das jeweilige Elternobjekt, und im Layout setzen Sie ein `<Outlet />` an die Stelle, wo diese Kinder erscheinen sollen. Diese letzten beiden Schritte gehören zusammen — die Verschachtelung im Datenobjekt und der Platzhalter im Markup sind zwei Seiten derselben Sache.
3:34 Lesen Sie diesen Baum wie eine Gliederung. Ganz oben steht der Wurzelpfad mit dem Layout, und darin verschachtelt die Kindrouten — eine davon mit dem Merkmal `index`, das heißt schlicht: Das ist die Ansicht, wenn keine Unterseite gewählt ist. Wichtig ist, was hier nicht steht. Das Layout erscheint kein zweites Mal, obwohl beide Kindrouten es benutzen.
3:54 Es wird einmal gerendert und bleibt beim Navigieren stehen — nur der Inhalt am `<Outlet />` tauscht. Bei einer geöffneten Seitenleiste oder einem Scrollzustand merkt man sofort, wie angenehm das ist: Beides bleibt erhalten. Jetzt bauen Sie selbst. Das Lernziel sind verschachtelte Routen mit einem gemeinsamen Layout — die Struktur, die praktisch jede reale Anwendung braucht.
4:17 Der Erfolg ist doppelt geprüft: Zwei Seiten teilen sich dieselbe Navigation, und der Wechsel läuft ohne Neuladen der Seite. Achten Sie beim Klicken einmal bewusst auf den Browser — kein Flackern, kein Fortschrittsbalken. Das ist der ganze Sinn der Übung. Als Erweiterung ergänzen Sie eine dynamische Route mit einem Parameter in der Adresse, also etwa eine Nutzer-ID im Pfad.
4:40 Die ersten drei Punkte haben dasselbe Symptom: Es passiert nichts, und Sie sehen nicht warum. Ein vergessenes `<Outlet />` bedeutet, dass die Kindroute korrekt gefunden wird — aber keinen Platz zum Erscheinen hat. Ein nicht montierter `RouterProvider` schaltet das Routing komplett stumm. Absolute und relative Pfade in den `children` zu mischen führt zu Adressen, die nicht dort landen, wo man denkt.
5:04 Der letzte Punkt ist der sichtbarste: Ein normales `a href` löst einen vollständigen Seiten-Reload aus. Ihre Anwendung startet komplett neu, aller Zustand ist weg. Deshalb immer `<Link>` — das ist keine Stilfrage.
Code Splitting & Lazy Loading
5:17 Der Routenbaum steht — und damit ergibt sich eine schöne Gelegenheit. Denn wenn die Anwendung ohnehin in Seiten aufgeteilt ist, muss der Nutzer beim Start gar nicht alles herunterladen. Genau da setzt das zweite Kapitel an. Standardmäßig backt der Build-Prozess Ihre gesamte Anwendung in eine große JavaScript-Datei. Der Nutzer lädt sie beim ersten Aufruf komplett — auch die Verwaltungsseite, die er vielleicht nie öffnet.
5:43 Code Splitting zerteilt dieses Paket in Stücke, die erst bei Bedarf kommen. Der Vergleich mit dem Umzug trifft es gut: Sie müssen nicht alle Kisten gleichzeitig ins Haus tragen, die für den Dachboden können warten. Technisch übernimmt `React.lazy` das Nachladen, und `<Suspense>` überbrückt die Wartezeit mit einer Anzeige.
6:02 Routen sind dafür die natürliche Schnittstelle — jede Seite ihr eigenes Paket. Das Argument ist schlicht Zeit. Was nicht geladen wird, muss auch nicht geparst und ausgeführt werden, und beides kostet auf einem durchschnittlichen Mobilgerät spürbar mehr als im Entwickler-Notebook. Selten besuchte Bereiche — Einstellungen, Verwaltung, ein aufwendiger Editor — belasten den Start dann nicht mehr.
6:25 Nachgeladen wird erst beim Aufruf, also genau dann, wenn es jemand tatsächlich braucht. Und der letzte Punkt ist der, der Ihren Chef interessiert: Die Kern-Web-Vitals verbessern sich, ohne dass Sie eine Zeile Fachlogik anfassen. Es ist eine der wenigen Optimierungen mit gutem Aufwand-Nutzen-Verhältnis. Zwei Handgriffe, dann drei Ratschläge. Die Route-Komponente wird per `React.lazy` mit einem dynamischen Import geladen, und um sie herum kommt ein `<Suspense>` mit einem Fallback.
6:54 Dieser Fallback verdient Aufmerksamkeit — er ist das, was Ihre Nutzer tatsächlich sehen, also lohnt sich etwas Aussagekräftigeres als ein zuckender Kreis. Punkt vier ist die Maßhaltung: Splitten Sie an sinnvollen Grenzen, also typischerweise pro Route, nicht pro Datei. Und prüfen Sie das Ergebnis im Netzwerk-Tab. Erst dort sehen Sie schwarz auf weiß, ob die Aufteilung wirklich greift oder ob doch alles im Hauptpaket landet.
7:20 Das Entscheidende steht in der ersten Zeile, und es ist die Klammer nach `import`. Ein normaler Import wird beim Bauen aufgelöst und wandert ins Hauptpaket. Diese Schreibweise dagegen ist ein Versprechen — der Bundler erkennt sie, legt daraus ein eigenes Paket an und lädt es erst, wenn die Zeile tatsächlich ausgeführt wird.
7:39 Darunter das `<Suspense>` mit seinem Fallback: React zeigt diesen Platzhalter, bis das Modul da ist, und tauscht dann auf die echte Komponente. Sie schreiben also nirgends eine Ladelogik — kein Statusflag, keine Abfrage. Das ist der eigentliche Komfort dieses Musters. In dieser Übung machen Sie eine Route nachladbar. Das Lernziel ist das Zusammenspiel aus `React.lazy` und `<Suspense>`.
8:02 Das Erfolgskriterium ist bewusst messbar formuliert: Im Netzwerk-Tab muss das Paket der Route erst auftauchen, wenn Sie dorthin navigieren — nicht schon beim Start. Werfen Sie vorher einen Blick auf den Ist-Zustand, dann sehen Sie den Unterschied unmittelbar. Als Erweiterung ersetzen Sie den einfachen Fallback durch einen Skeleton, der die spätere Struktur schon andeutet.
8:23 Das wirkt für den Nutzer deutlich schneller, obwohl technisch nichts schneller geworden ist. Ein `<Suspense>` ohne Fallback zeigt beim Laden gar nichts — technisch korrekt, für den Nutzer ein weißer Bildschirm. Der zweite Punkt ist die typische Übertreibung: Wer jede Datei einzeln splittet, bekommt Dutzende Mini-Pakete, und der Aufwand für die vielen Anfragen frisst den Gewinn wieder auf.
8:46 Der dritte ist ein handfester Stolperstein beim Tippen — `lazy` erwartet einen Default-Export; bei einem Named-Export bricht es, mit einer Meldung, die einen nicht sofort auf die Spur bringt. Und denken Sie an den Netzfehler: Ohne Error Boundary bleibt bei einem fehlgeschlagenen Nachladen die Seite einfach weiß.
Protected Routes & Navigation Guards
9:04 Nicht jeder Bereich einer Anwendung geht jeden etwas an. Wie man Routen an eine Bedingung koppelt und Nutzer umleitet, sehen wir jetzt — mit einer wichtigen Einordnung gleich vorweg, denn hier wird oft etwas verwechselt. Eine geschützte Route prüft vor dem Rendern eine Bedingung und leitet um, wenn sie nicht erfüllt ist. Meistens geht es um den Login-Status.
9:24 Technisch ist das eine Wrapper-Komponente, die entweder ihre Kinder durchlässt oder ein `<Navigate>` zurückgibt. Und jetzt die Einordnung, die auf der Notizzeile steht und die ich gern doppelt unterstreiche: Das ist keine Sicherheit. Denken Sie an ein Schild "Zutritt nur für Personal" — es lenkt Leute, die sich daran halten, aber es ist kein Schloss.
9:45 Alles, was im Browser läuft, kann der Nutzer sehen und umgehen. Der Guard ist Bequemlichkeit, nicht Schutz. Trotz dieser Einschränkung ist ein Guard sehr nützlich. Er hält Nutzer von Seiten fern, auf denen sie ohnehin nur Fehlermeldungen sehen würden, weil das Backend die Daten verweigert — das ist schlicht bessere Bedienbarkeit.
10:04 Er bündelt die Prüfung an einer Stelle statt in jeder einzelnen Komponente, und damit haben Sie einen Ort, an dem Sie Regeln ändern können. Der dritte Punkt ist der, den Nutzer am meisten zu schätzen wissen: das Ziel merken. Wer einen Deep-Link zu einem Dokument anklickt, sich einloggt und dann auf der Startseite landet, ärgert sich zu Recht.
10:23 Der Ablauf ist überschaubar. Sie lesen den Auth-Status aus Ihrem Context oder Store, legen einen Wrapper um die geschützten Routen und leiten bei fehlender Berechtigung per `<Navigate>` zum Login. Punkt vier ist der Feinschliff, der den Unterschied macht: Geben Sie die aktuelle Adresse als Zustand mit, damit Sie nach dem Login dorthin zurückspringen können.
10:43 Und Punkt fünf wiederholt bewusst, was wir schon gesagt haben — die serverseitige Prüfung ist nicht optional. Der Guard verbessert das Erlebnis, das Backend entscheidet. Diese Trennung sollte in jedem Projekt klar sein. Das ganze Muster passt in fünf Zeilen, und es liest sich wie ein Satz: Ist kein Nutzer da, geh zum Login — sonst zeige, was drinsteht. Interessant ist der Zusatz im `<Navigate>`.
11:06 Dort wird die aktuelle Adresse als Zustand mitgegeben, und die Login-Seite kann sie nach erfolgreicher Anmeldung wieder auslesen und dorthin zurückspringen. Das sind zwei zusätzliche Wörter im Code und ein spürbarer Unterschied in der Bedienung. Was hier übrigens fehlt, ist der Ladezustand — solange der Auth-Status noch geprüft wird, ist der Nutzer weder eingeloggt noch ausgeloggt. Dazu gleich mehr bei den Stolpersteinen.
11:31 Jetzt sichern Sie selbst eine Route ab. Das Lernziel ist, den Zugriff an eine Bedingung zu koppeln und andernfalls sauber umzuleiten. Das Erfolgskriterium hat zwei Teile: Ohne Login landet der Aufruf auf der Login-Seite — und nach dem Login geht es zurück zum ursprünglichen Ziel. Gerade dieser zweite Teil ist der, den man in der Praxis am häufigsten weglässt und der am meisten Ärger erspart.
11:54 Testen Sie ihn ausdrücklich, indem Sie den Deep-Link direkt in die Adresszeile eingeben. Die Erweiterung baut genau diesen Rücksprung gezielt aus. Der erste Punkt steht hier zum dritten Mal, und das mit Absicht: Ein Guard ist keine Autorisierung. Der zweite betrifft das vergessene Ziel — der Nutzer landet nach dem Login auf der Startseite und muss sich neu durchklicken.
12:16 Die Redirect-Schleife entsteht, wenn die Login-Seite selbst versehentlich hinter dem Guard liegt: umleiten zum Login, Login ist geschützt, umleiten zum Login. Der Browser dreht sich, bis er aufgibt. Und der letzte ist der subtilste: Während der Auth-Status noch geladen wird, ist der Nutzer noch nicht eingeloggt — leiten Sie dann sofort um, fliegt jeder beim Neuladen erst einmal zum Login.
12:38 Zeigen Sie solange einen Ladezustand.
SEO-optimierte SPA-Navigation
12:40 Kommen wir zum Thema, das bei Single-Page-Anwendungen traditionell der wunde Punkt ist. Ihre Anwendung mag im Browser hervorragend funktionieren — die Frage ist, was eine Suchmaschine davon sieht. Und die Antwort ist ohne Zutun oft ernüchternd. Eine klassische SPA liefert an den Browser zunächst ein fast leeres HTML-Dokument; alles Sichtbare entsteht erst, wenn JavaScript gelaufen ist.
13:04 Für einen Menschen sind das Millisekunden. Für einen Crawler ist es ein Problem — er sieht im Zweifel ein leeres Grundgerüst und zieht weiter. Die Antwort besteht aus zwei Teilen. Erstens serverseitiges Rendern oder Prerendering, damit fertiges HTML ausgeliefert wird. Zweitens eigene Titel und Meta-Angaben pro Route, denn genau daraus baut die Suchmaschine ihren Eintrag in der Ergebnisliste.
13:28 Beides zusammen macht aus einer unsichtbaren Anwendung eine auffindbare. Ob das für Sie relevant ist, hängt vom Projekt ab — bei einem internen Verwaltungswerkzeug hinter dem Login interessiert kein Crawler. Bei allem Öffentlichen entscheidet es mit über den Erfolg. Server-Rendering liefert fertiges HTML pro Route, und damit sieht der Crawler dasselbe wie der Mensch.
13:50 Eigene Titel und Beschreibungen bestimmen, was in der Ergebnisliste steht — das ist der Text, auf den jemand klickt oder eben nicht. Und echte `<Link>`-Navigation sorgt dafür, dass Bots Ihren Seiten überhaupt folgen können. Ein Klick-Handler ist für sie schlicht kein Verweis. Punkt eins ist eine Architekturentscheidung, die früh fallen sollte: SSR oder Prerendering nachträglich einzubauen ist deutlich aufwendiger, als von Anfang an den Framework-Modus zu nutzen.
14:17 Punkt zwei ist Disziplin — jede Navigation läuft über `<Link>`, ausnahmslos. Titel und Meta-Angaben setzen Sie pro Route, und das geht seit Version 19 erfreulich direkt, wie wir gleich sehen. Eine Sitemap und sprechende Adressen sind Handwerk, das oft liegen bleibt. Und der letzte Punkt ist der ehrliche Test: Schauen Sie mit einem Crawler-Werkzeug nach, was tatsächlich ankommt. Vermuten reicht hier nicht.
14:42 Diese Folie zeigt eine der angenehmsten Neuerungen von React 19. Sie schreiben `<title>` und `<meta>` einfach mitten in Ihre Komponente, an die Stelle, wo die Daten ohnehin vorliegen — und React hebt sie automatisch dorthin, wo sie hingehören, in den `<head>` des Dokuments. Wer das vorher gemacht hat, brauchte dafür eine eigene Bibliothek wie React Helmet. Dieser Umweg entfällt.
15:04 Der Gewinn ist nicht nur weniger Abhängigkeit, sondern vor allem Nähe: Titel und Beschreibung stehen bei den Daten, aus denen sie entstehen. Damit ist es wesentlich unwahrscheinlicher, dass sie beim Ändern vergessen werden. In dieser Übung machen Sie eine Route auffindbar. Das Lernziel verbindet beide Aspekte des Kapitels: eigene Meta-Informationen und crawlbare Navigation.
15:26 Der Erfolg ist gut prüfbar — die Route liefert einen eigenen Titel und eine eigene Beschreibung, und jeder Wechsel läuft über `<Link>`. Schauen Sie sich den Tab-Titel im Browser an, während Sie navigieren; er sollte mitwandern. Als Erweiterung rendern Sie die Seite serverseitig und sehen sich die tatsächlich ausgelieferte HTML-Ausgabe an.
15:46 Erst dieser Blick auf den Quelltext zeigt, was ein Crawler wirklich bekommt. Der erste Punkt ist der teuerste: Navigation über einen Klick-Handler statt über `<Link>`. Für den Nutzer sieht das identisch aus, für einen Crawler existiert dieser Weg schlicht nicht — ganze Bereiche bleiben dann unentdeckt. Der zweite ist Wunschdenken: Ohne SSR oder Prerendering auf gutes Ranking zu hoffen, geht meistens schief.
16:11 Der dritte ist Nachlässigkeit, die man in jeder Ergebnisliste sieht — alle Unterseiten mit demselben Titel, entsprechend nichtssagende Einträge. Und der letzte ist seit Version 19 überflüssig geworden: Meta-Tags im Effekt zu setzen ist zu spät für den Crawler. Rendern Sie sie einfach. Ziehen wir die Linie. Der Routenbaum entsteht als Datenstruktur mit `createBrowserRouter`, gemeinsame Rahmen teilen sich Seiten über das `<Outlet />`.
16:37 Geschwindigkeit kommt fast geschenkt, wenn jede Route ihr eigenes Paket bekommt und `<Suspense>` die Wartezeit überbrückt. Zugriffsschutz läuft über einen Wrapper mit `<Navigate>` — mit gemerktem Ziel und in dem klaren Bewusstsein, dass die echte Prüfung im Backend stattfindet. Und Auffindbarkeit braucht zweierlei: serverseitiges Rendern und eigene Meta-Angaben pro Route, was React 19 endlich ohne Zusatzbibliothek erlaubt.
17:02 Von der ersten Route bis zur crawlbaren Navigation.
Fragen & Weiterarbeiten
17:06 Damit sind wir am Ende. Alle Beispiele und Routenbäume liegen in der Freigabe — gerade den Guard mit dem Rücksprung nach dem Login würde ich mir noch einmal in Ruhe ansehen, der lohnt sich in jedem Projekt. Für alles Weitere gibt es zwei gute Adressen: reactrouter.com für alles rund um den Router, react.dev für die React-Seite, etwa die neuen Head-Elemente aus Kapitel vier.
17:28 Beide sind aktuell gepflegt, was bei diesem Thema wichtig ist — zwischen Router Version 5 und 7 liegen Welten. Bei Fragen im Projektalltag erreichen Sie uns unter der Adresse auf der Folie. Vielen Dank.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →