SPA Subdomain Root Rendern ohne Weiterleitung
Problem
Beim Aufbau subdomain-basierter Routen (z. B. username.example.com) ändert die Verwendung von React ROuters <Navigate to="/profile/username" replace /> die URL, was den Zweck einer sauberen Subdomain-URL zunichte macht. Zudem kann die Zielkomponente eine leere Seite anzeigen, wenn sie auf useParams() angewiesen ist, um Routenparameter zu erhalten, die unter / nicht existieren.
Kontext / Auslösebedingungen
- Die Subdomain-Profilseite leitet auf
/profile/npub1...weiter, anstatt den Inhalt unter/bereitzustellen - Die Seite erscheint leer (kein Inhalt wird geladen) auf dem Subdomain-Stammverzeichnis
- Die Komponente verwendet
useParams()und schlägt fehl, wenn sie auf einer Route ohne diese Parameter gerendert wird - Der Edge Worker injiziert Benutzerdaten in
window.__SUBDOMAIN_USER__oder ein ähnliches Global - Es soll
username.domain.com/wie eine persönliche Website aussehen
Lösung
1. Router: Komponente direkt rendern statt Navigieren
Vorher (verursacht Weiterleitung + URL-Änderung):
<Route path="/" element={
subdomainUser
? <Navigate to={`/profile/${subdomainUser.npub}`} replace />
: <Index />
} />
Nachher (rendert unter / ohne URL-Änderung):
<Route path="/" element={
subdomainUser
? <ProfilePage />
: <Index />
} />
2. Komponente: Fallback-Datenquelle hinzufügen
Die Komponente muss auf injizierte Subdomain-Daten zurückgreifen, wenn Routenparameter fehlen.
Vorher (prüft nur Routenparameter):
export function ProfilePage() {
const { npub } = useParams<{ npub?: string }>();
const identifier = npub;
if (!identifier) {
return <Error message="Keine Benutzerkennung bereitgestellt" />;
}
// ... Rest der Komponente
}
Nachher (greift auf injizierte Daten zurück):
import { getSubdomainUser } from '@/hooks/useSubdomainUser';
export function ProfilePage() {
const { npub } = useParams<{ npub?: string }>();
const subdomainUser = getSubdomainUser();
// Routenparam hat Priorität, Subdomain-Daten sind Fallback
const identifier = npub || subdomainUser?.npub;
if (!identifier) {
return <Error message="Keine Benutzerkennung bereitgestellt" />;
}
// ... Rest der Komponente
}
3. Edge Worker: Benutzerdaten in HTML injizieren
Der Edge Worker (Fastly Compute, Cloudflare Workers u.ä.) sollte Benutzerdaten injizieren:
// Im Edge Worker, der die Subdomain behandelt
const userData = await fetchUserData(username);
const html = await fetchSpaHtml();
const injectedHtml = html.replace(
'</head>',
`<script>window.__DIVINE_USER__ = ${JSON.stringify(userData)};</script></head>`
);
return new Response(injectedHtml, { headers: { 'content-type': 'text/html' } });
4. Clientseitiger Datenzugriff
// useSubdomainUser.ts
interface SubdomainUser {
subdomain: string;
pubkey: string;
npub: string;
username?: string;
displayName?: string;
// ... weitere Felder
}
export function getSubdomainUser(): SubdomainUser | null {
if (typeof window === 'undefined') return null;
return (window as any).__DIVINE_USER__ || null;
}
Überprüfung
- Besuche
username.domain.com/- die URL sollte bei/bleiben, nicht weiterleiten - Der Profilinhalt sollte korrekt geladen werden
- Überprüfe die Browserkonsole auf keine Fehler bezüglich fehlender Kennungen
- Verifiziere
window.__DIVINE_USER__in den DevTools enthält die erwarteten Daten
Beispiel
Für divine-web:
thecomedianriley.divine.video/rendert ProfilePage unter/- ProfilePage prüft zuerst
useParams()(leer bei/) - Greift zurück auf
getSubdomainUser()?.npubaus den injizierten Daten - Profil lädt ohne URL-Änderung
Hinweise
- Dieses Muster erfordert Koordination zwischen Edge Worker und Client-Code
- Der Edge Worker muss Daten vor der SPA-Hydration injizieren
- Immer zuerst Routenparameter prüfen, damit normale
/profile/:npub-Routen weiterhin funktionieren - SEO beachten: Der Edge Worker sollte auch angemessene Meta-Tags setzen
- Links auf der Subdomain können die
SmartLink-Komponente verwenden, um lokal für den Besitzer zu bleiben, aber für Inhalte anderer Benutzer auf die Apex-Domain zu verlinken
Referenzen
- React Router v6 Routes: https://reactrouter.com/en/main/route/route
- Fastly Compute@Edge: https://developer.fastly.com/learning/compute/