Routing in Apps
Das Sachbearbeiter-Cockpit bringt den Router mit und reserviert sich davon nur zwei Ebenen: die Übersicht und den App-Bereich. Alles unterhalb einer App gehört der App selbst.
Die URL-Struktur
/ App-Übersicht (Kachel-Grid)
/:appId/* eine App – alles darunter macht die App selbst
alles andere → Weiterleitung auf /
:appId ist die id aus der CockpitApp.
Eine App mit id: 'akten' liegt also unter /akten, ihre Unterseiten unter
/akten/….
Beim Klick auf eine Kachel navigiert das Sachbearbeiter-Cockpit relativ auf app.id; der
Home-Button in der Kopfzeile erscheint, sobald der Pfad nicht mehr / ist, und
führt zurück auf die Übersicht.
Routen innerhalb der App
Die App wird unter :appId/* gemountet — sie bekommt also einen Splat und darf
darunter beliebig eigene <Routes> aufspannen. Die Pfade sind relativ, ohne
führenden Slash:
import { Routes, Route } from 'react-router';
import type { AppComponent } from '@gentics/cockpit/core';
export const AktenApp: AppComponent = () => (
<Routes>
<Route index element={<AktenListe />} />
<Route path=":fileId" element={<AktenDetail />} />
<Route path=":fileId/dokumente" element={<AktenDokumente />} />
<Route path="einstellungen" element={<Einstellungen />} />
</Routes>
);
| Route in der App | Ergebnis-URL |
|---|---|
index | /akten |
:fileId | /akten/<id> |
:fileId/dokumente | /akten/<id>/dokumente |
einstellungen | /akten/einstellungen |
<Route path="/detail"> innerhalb der App ist eine absolute Route unter
einem Elternpfad und damit ungültig — React Router bricht mit
„Absolute route path … nested under path … is not valid" ab. Also immer
path="detail" statt path="/detail".
Navigieren
import { useNavigate, useParams, Link } from 'react-router';
const navigate = useNavigate();
navigate(fileId); // relativ: /akten/<id>
navigate('..'); // eine Ebene zurück
navigate('/'); // zurück zur App-Übersicht des Sachbearbeiter-Cockpits
navigate(-1); // Browser-History zurück
<Link to={`${fileId}/dokumente`}>Dokumente</Link>
const { fileId } = useParams(); // Parameter der eigenen Route lesen
react-router kommt als Peer-Dependency aus deinem Projekt — du importierst
useNavigate, Routes & Co. also direkt aus react-router, nicht aus
@gentics/cockpit.
Router-Modi
Welchen Router das Sachbearbeiter-Cockpit stellt, bestimmt die Prop router:
| Modus | Verhalten | Wann |
|---|---|---|
"hash" (Default) | Eigener HashRouter, URLs wie /#/akten/<id> | Kein Server-Setup nötig — die sichere Wahl, auch beim Ausliefern aus einem Unterordner |
"browser" | Eigener BrowserRouter, saubere URLs (/akten/<id>) | Nur wenn der Host einen SPA-Fallback liefert: jeder Pfad muss index.html ausliefern, sonst 404 beim Reload oder Deep-Link |
"none" | Kein eigener Router | Wenn der einbettende Host schon einen Router mitbringt — verhindert zwei verschachtelte Router |
Bei router="browser" und einem Sachbearbeiter-Cockpit unter einem Unterpfad gehört zusätzlich
basename gesetzt:
<BaseCockpit apps={apps} router="browser" basename="/cockpit" />
Einbetten in einen fremden Router
Bringt die umgebende Anwendung bereits einen Router mit, ist router="none" die
richtige Wahl — ein zweiter, verschachtelter Router würde sonst um die URL
konkurrieren.
Zu beachten: Das Sachbearbeiter-Cockpit registriert seine Routen als / und :appId/*. Die
Route / ist absolut und muss deshalb zum Elternpfad passen. In der Praxis
heißt das: das Sachbearbeiter-Cockpit muss im fremden Router an der Wurzel sitzen.
// Funktioniert: Sachbearbeiter-Cockpit an der Wurzel des Host-Routers
<BrowserRouter>
<BaseCockpit apps={apps} router="none" />
</BrowserRouter>
Für ein Sachbearbeiter-Cockpit unterhalb eines Host-Pfads (z. B. /verwaltung/cockpit/*) gibt
es in der Library derzeit keinen vorgesehenen Weg — der Fall ist nicht
abgedeckt.
Deep-Links
Deep-Links funktionieren ohne Zutun der App: das Sachbearbeiter-Cockpit löst :appId aus der
URL auf und mountet die passende App. Dabei gilt:
- Unbekannte
:appId→ Weiterleitung auf/. - Ist die Rechteprüfung aktiv (
checkPermission), wird sie auch hier erneut geprüft — nicht nur beim Klick auf eine Kachel. Fehlt die Rolle, landet der User auf der Übersicht. Siehe Auth & Rechte. - Beim Wechsel zwischen Apps wird der Tenant-Context neu aufgebaut (der Provider ist an die App-Id gebunden). App-lokaler State überlebt einen App-Wechsel also nicht.
- Bei
router="browser"braucht der Server den SPA-Fallback, sonst endet der Deep-Link im 404 des Webservers, bevor das Sachbearbeiter-Cockpit überhaupt lädt.
