History-Router für destination.one Web Components
Diese Anleitung richtet sich an Agenturen und Entwicklungsteams, die destination.one Web
Components in eine bestehende Website oder ein CMS integrieren. Sie beschreibt, wie der
History-Router im Browser und das dafür erforderliche Routing auf dem Webserver konfiguriert
werden.
Kurzfassung
Für normale, direkt aufrufbare URLs wie
sind zwei Einstellungen erforderlich:
1. Das Loader-Script der Web Components verwendet `data-router-mode="history"` und den
vollständigen Einhängepfad als `data-base-path`.
2. Der Webserver oder das CMS liefert für alle Web-Component-Routen unter diesem Pfad intern die
Einbindungsseite aus. Die angeforderte URL bleibt dabei im Browser erhalten.
Ohne die Serverregel funktionieren Navigationen innerhalb der bereits geladenen Seite, ein
Neuladen oder direkter Aufruf einer Detail-URL endet jedoch üblicherweise mit einem HTTP-404.
Was ist der History-Router?
Die Web Components verwenden clientseitiges Routing. Beim Wechsel von einer Ergebnisliste auf
eine Detailseite wird nicht zwingend ein neues HTML-Dokument vom Server geladen. Stattdessen
aktualisiert der Router den sichtbaren Inhalt und – abhängig vom Router-Modus – die Browser-URL.
Modus | Beispiel | Server-Fallback | Geeignet für indexierbare Detail-URLs |
memory | URL der Einbindungsseite bleibt unverändert | nein | nein |
hash | /de/erleben#/detail/POI/... | nein | nein |
history | /de/erleben/detail/POI/... | ja | ja |
Der History-Modus nutzt normale URL-Pfade ohne `#`. Daraus ergeben sich folgende Vorteile:
- Detailseiten besitzen lesbare, kopier- und teilbare URLs.
- Links können direkt auf eine Ergebnisliste oder Detailseite verweisen.
- Vorwärts- und Zurück-Navigation des Browsers bilden die Navigation der Web Components ab.
- Die URLs können in der WC-Sitemap ausgegeben und von Suchmaschinen gefunden werden.
- Tracking- und Analysewerkzeuge können Seitenwechsel anhand normaler Pfade unterscheiden.
Der History-Modus allein garantiert keine Indexierung. Er schafft die technische Voraussetzung
für normale URLs; Statuscode, Crawlability, Canonical-URL und Inhalt müssen ebenfalls stimmen.
URL-Schema
Die relevanten Routen werden an den konfigurierten Einhängepfad angehängt:
- {basePath}/search/{dataType}/{filter?}
- {basePath}/detail/{dataType}/{globalId}/{slug?}
- {basePath}/dayplanner/{filter?}
Für eine Einbindungsseite unter `/de/erleben` entstehen beispielsweise:
- /de/erleben/search/POI
- /de/erleben/detail/POI/p_1000123/aussichtsturm
Der optionale Slug verbessert die Lesbarkeit. Für die Zuordnung des Datensatzes ist die
`globalId` maßgeblich.
Web Components konfigurieren
Die Router-Konfiguration gehört an das Loader-Script `web-components.js`. Sie gilt gemeinsam für
alle routingfähigen destination.one Web Components auf der Seite.
`data-router-mode`
Der Wert muss `history` sein. Fehlt das Attribut oder enthält es einen ungültigen Wert, verwenden
die Web Components standardmäßig den Modus `memory`.
`data-base-path`
Der Base-Path ist der vollständige URL-Pfad der Seite, auf der die routingfähigen Web Components
eingehängt sind. Er beginnt mit `/`, enthält keine Domain, keine Query-Parameter und kein
Fragment. Ein abschließender Slash ist nicht erforderlich.
Öffentliche Einbindungsseite | Passender Base-Path |
| /erleben |
| /de/erleben |
| / |
Sprachsegmente des Hostsystems gehören somit zum Base-Path, sofern sie Bestandteil der
öffentlichen URL sind. `data-base-path`, Serverregel und öffentliche Einbindungsseite müssen exakt
zueinander passen.
Das Loader-Script sollte pro HTML-Dokument nur einmal eingebunden werden. Da die routingfähigen
Web Components einen gemeinsamen Router verwenden, können sie auf derselben Seite nicht mit
unterschiedlichen Router-Modi oder Base-Paths betrieben werden.
Beispiel: Ergebnisliste mit Detailseiten
- <script
- type="module"
- src="https://newpages.destination.one/web-components.js"
- data-language="de"
- data-experience="destination-one"
- data-template="wlan"
- data-router-mode="history"
- data-base-path="/de/erleben"
- ></script>
- <done-result-list
- type="POI"
- layout="card"
- map="half"
- limit="20"
- sort="highlights"
- ></done-result-list>
Der Ablauf ist dann:
- Die Agenturseite wird unter `https://www.agentur.de/de/erleben` ausgeliefert.
- Die Ergebnisliste bildet ihren Zustand in einer Route wie `/de/erleben/search/POI` ab.
- Ein Klick auf einen Treffer navigiert clientseitig zu einer URL wie `/de/erleben/detail/POI/p_1000123/aussichtsturm` und zeigt die Detailansicht.
- Beim direkten Aufruf oder Neuladen dieser Detail-URL erhält der Webserver einen echten Request für genau diesen Pfad. Er muss intern wieder die Einbindungsseite aus Schritt 1 ausliefern.
- Nach dem Laden liest der History-Router die erhaltene URL und zeigt unmittelbar die passende Detailansicht.
Das `<done-result-list>` benötigt kein eigenes Router-Attribut. Die Konfiguration wird zentral vom
Loader-Script übernommen.
Webserver oder CMS konfigurieren
Ziel der Serverregel
Für die bekannten Web-Component-Routen unterhalb des Base-Paths muss der Server die HTML-Seite
ausliefern, welche das Loader-Script und das Web Component enthält.
Für einen Request auf
- /de/erleben/detail/POI/p_1000123/aussichtsturm
liefert der Server daher intern den Inhalt der Einbindungsseite `/de/erleben` aus. Dabei gelten
folgende Anforderungen:
- Die URL in der Adresszeile bleibt die angeforderte Detail-URL.
- Die Antwort hat für eine gültige, öffentlich erreichbare Detailseite den Status `200`.
- Es erfolgt kein `301`- oder `302`-Redirect zurück auf `/de/erleben`.
- Vorhandene Dateien und Verzeichnisse, API-Endpunkte sowie andere Website-Routen bleiben von der Fallback-Regel ausgenommen.
- Die Regel wird möglichst auf `search`, `detail` und `dayplanner` innerhalb des Base-Paths begrenzt. Ein globales Fallback auf jede unbekannte URL würde echte Fehlerseiten verschleiern.
Die folgenden Beispiele verwenden `/de/erleben` als Base-Path. Pfad und Ziel müssen an das
jeweilige Hosting beziehungsweise CMS angepasst werden.
Nginx: statische Einbindungsseite
Wenn die Einbindungsseite als `/de/erleben/index.html` vorliegt:
- location ~ ^/de/erleben/(?:search|detail|dayplanner)(?:/.*)?$ {
- try_files $uri /de/erleben/index.html;
- }
Die reguläre Konfiguration für `/de/erleben` und statische Dateien bleibt daneben bestehen.
Nginx: Einbindungsseite aus einem CMS
Wenn die bestehende CMS-Konfiguration die Route `/de/erleben` rendert, kann die WC-Route intern
auf diese Route umgeschrieben werden:
- location ~ ^/de/erleben/(?:search|detail|dayplanner)(?:/.*)?$ {
- rewrite ^ /de/erleben last;
- }
Die CMS-Front-Controller-Regel verarbeitet anschließend `/de/erleben`. Es handelt sich um einen
internen Rewrite; die öffentlich sichtbare Detail-URL wird nicht geändert.
Apache HTTP Server
Beispiel für eine `.htaccess` im Document-Root mit `mod_rewrite`:
- RewriteEngine On
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteRule ^de/erleben/(search|detail|dayplanner)(/.*)?$ /de/erleben [L]
Bei einer statischen Integration wird als Ziel stattdessen die tatsächliche HTML-Datei, zum
Beispiel `/de/erleben/index.html`, verwendet. In VirtualHost-Konfigurationen kann sich das
Matching von Regeln in `.htaccess` unterscheiden; dort ist das Muster entsprechend anzupassen.
CMS und Reverse Proxies
Bei einem CMS wird die Regel je nach System als Catch-all-Route, Rewrite oder Middleware
umgesetzt. Bei einem Reverse Proxy kann die angeforderte WC-Route an denselben Upstream wie die
Einbindungsseite geleitet und dort intern auf diese Seite aufgelöst werden.
Unabhängig von der Technik ist das Ergebnis immer gleich: Der Browser behält den Deep-Link, der
Server liefert Status `200` und den HTML-Rahmen der Einbindungsseite, anschließend rendert das Web
Component die angeforderte Route.
SEO und WC-Sitemap
Der History-Modus ist Voraussetzung dafür, dass Detailseiten als normale URLs in der WC-Sitemap
erscheinen. Hash-URLs werden für diesen Anwendungsfall nicht erzeugt.
Die vollständige Einrichtung der zentral bereitgestellten Sitemap, ihre Parameter, die
`robots.txt`-Einträge und die SEO-Prüfpunkte sind in der destination.one Knowledge Base erklärt:
Für das obige Beispiel muss die `baseUrl` der Sitemap mit der öffentlich kanonischen URL und dem
Einhängepfad übereinstimmen:
Diese URL wird gemäß der Sitemap-Dokumentation als `Sitemap:`-Eintrag in der `robots.txt`
referenziert. Für jede verwendete Kombination aus Datentyp und Sprache ist ein passender Eintrag
erforderlich.
Wichtig: `data-detail-link-mode="canonical"` kann interne Links auf abweichende, vom Datensatz
vorgegebene Canonical-URLs lenken. Vor der Sitemap-Einbindung muss deshalb sichergestellt werden,
dass interne Links, Canonical-Tag und Sitemap-URL dasselbe URL-Konzept verwenden.
Inbetriebnahme prüfen
Nach der Konfiguration sollten mindestens folgende Fälle geprüft werden:
1. Einbindungsseite öffnen und einen Treffer aus der Ergebnisliste anklicken.
2. Prüfen, dass die Adresszeile eine History-URL ohne `#` zeigt.
3. Die Detailseite neu laden; sie muss weiterhin Inhalt und HTTP-Status `200` liefern.
4. Die kopierte Detail-URL in einem privaten Browserfenster direkt öffnen.
5. Vor- und Zurück-Navigation zwischen Ergebnisliste und Detailseite testen.
6. Sicherstellen, dass ein unbekannter Pfad außerhalb der WC-Routen weiterhin einen echten `404`
liefert.
7. Prüfen, dass `robots.txt`, Robots-Meta-Tag oder Authentifizierung die Seite nicht blockieren.
8. Canonical-URL und eine von der WC-Sitemap ausgegebene URL exakt vergleichen.
Der Status und mögliche Redirects lassen sich zusätzlich auf der Kommandozeile kontrollieren:
Erwartet werden `Status: 200` und eine leere `Redirect`-Zeile.
Häufige Fehler
Navigation funktioniert, Neuladen liefert aber 404
Der Browser-Router ist korrekt konfiguriert, aber die serverseitige Fallback- oder Rewrite-Regel
fehlt beziehungsweise greift nicht für den vollständigen Base-Path.
Die URL enthält weiterhin `#`
Das Loader-Script verwendet noch `data-router-mode="hash"`, die History-Konfiguration steht am
falschen Element oder es wird ein anderes `web-components.js`-Script gefunden als erwartet.
Die URL verliert ein Sprach- oder Pfadsegment
`data-base-path` enthält nicht den vollständigen öffentlichen Einhängepfad. Bei einer Seite unter
`/de/erleben` muss beispielsweise auch `/de/erleben` konfiguriert werden.
Direkter Aufruf leitet auf die Einbindungsseite um
Die Serverregel ist als externer Redirect statt als interner Rewrite umgesetzt. Dadurch geht die
Detail-URL verloren. Die Regel muss intern auf die Einbindungsseite auflösen.
Jede unbekannte URL liefert Status 200
Das Fallback ist zu weit gefasst. Es sollte auf den Base-Path und die bekannten WC-Routen begrenzt
werden, damit echte Fehler weiterhin als `404` erkennbar sind.