Single-Page-Apps und Seitenwechsel
Wie das Widget Seitenwechsel in React, Vue, Angular, Next.js, Turbo oder htmx selbst erkennt, was es dabei an den Server meldet, und was du in einer Single-Page-App beachten solltest.
In einer Single-Page-App lädt der Browser die Seite nur einmal; danach tauscht dein Framework Inhalte aus und ändert die Adresse per history.pushState. Das Widget erkennt diese Wechsel selbst. Du musst nichts melden und nichts neu starten.
Einbinden: genau einmal
Setze den Loader einmal in die Hülle deiner App (index.html, Root-Layout, _document), nicht in eine Komponente, die bei jedem Routenwechsel neu gerendert wird. Ein zweites Einbinden ist zwar harmlos (der zweite Loader tut nichts, siehe Script-Tag), ein Entfernen und Wiedereinsetzen des Tags startet das Widget aber nicht neu.
// Next.js (App Router), app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html lang="de">
<body>
{children}
<Script src="https://cdn.reactive.chat/loader.js"
data-rc-site-key="SITE_KEY"
strategy="afterInteractive" />
</body>
</html>
);
}
Ob ein Framework-Helfer die data-*-Attribute an das erzeugte <script> weitergibt, prüfst du am einfachsten im Element-Inspektor. Fehlt data-rc-site-key dort, startet nichts.
Wie Seitenwechsel erkannt werden
Das Widget greift nicht in history.pushState ein, es beobachtet nur:
- die Navigation API des Browsers (
navigation.currententrychange), wo vorhanden; - sonst
popstateundhashchange; - zusätzlich einen Takt, der Adressänderungen ohne Ereignis findet (jede Sekunde, mit Navigation API alle 5 Sekunden);
pageshowbei Rückkehr aus dem Back-/Forward-Cache.
Als Seitenwechsel zählt: eine neue Adresse (Pfad oder Query) und Hash-Routen der Form #/… und #!/….
Nicht als Seitenwechsel zählt: ein reiner Sprung zu einer Sprungmarke (#abschnitt) und replaceState auf dieselbe Adresse.
Was dabei gemeldet wird
400 ms nach dem Wechsel (damit Zwischenstände von Weiterleitungen nicht zählen) schickt das Widget einen Kontextrahmen an den Server – nur mit Einwilligung:
- url, path, title, referrer –
urlundreferrerwerden vorher von sensiblen Query-Parametern bereinigt (etwaemail,password,token,key,card). - locale, tz, viewport, screen, ua_hint.
- utm_source, utm_medium, utm_campaign, gclid, msclkid, fbclid aus der Adresse.
- nav – Art des Wechsels:
load,push,replace,reload,back,forwardodertraverse.
Setzt deine App den Titel erst nach dem Wechsel, schickt das Widget nach 2 Sekunden eine Korrektur. So sehen Agenten im Pult, auf welcher Seite der Besucher gerade ist, und der Assistent bezieht seine Antwort auf diese Seite.
Den sichtbaren Seitentext liest das Widget ebenfalls neu ein (für Antworten zur aktuellen Seite und für „Zeig's mir“) – frühestens 1,2 Sekunden nach der letzten Änderung, höchstens alle 5 Sekunden, nie auf Seiten wie Konto, Checkout oder Warenkorb und nie aus Formularfeldern. Bereiche, die der Assistent nicht lesen soll, markierst du mit data-rc-private (Script-Tag).
Eigenen Kontext je Seite mitgeben
Eine eigene Methode zum Melden eines Seitenwechsels gibt es nicht und braucht es nicht. Willst du zusätzliche Angaben zur aktuellen Seite mitgeben, etwa das angezeigte Produkt, nutze track nach dem Routenwechsel:
// React Router
const location = useLocation();
useEffect(() => {
if (produkt) {
window.ReactiveChat('track', 'produktseite', {
page_type: 'product', product_id: produkt.sku, price: produkt.preis,
currency: 'EUR', in_stock: produkt.lieferbar
});
}
}, [location.pathname, produkt]);
Welche Felder ankommen, steht unter Besucher identifizieren und Kontext übergeben.
Turbo, htmx, Livewire
Frameworks, die den ganzen <body> austauschen, entfernen dabei auch das Element des Widgets. Das Widget hängt sich dann selbst wieder ein (höchstens zehnmal je Minute); das Gespräch läuft weiter.
Angemeldete Nutzer in SPAs
Meldet sich jemand ohne Neuladen an, rufe danach identify mit frisch vom Server geholtem Hash auf. Wechselt der Nutzer, trennt das Widget den Eingabe-Entwurf vom vorigen Nutzer. Einzelheiten unter Besucher identifizieren.
Datenschutztext in SPAs
Fügt deine App die Datenschutzerklärung erst nach dem Laden ein, findet das Widget das Element data-rc-privacy trotzdem (es beobachtet das Dokument). Siehe Datenschutz-Einbindung.
Weiter: Sicherheit und CSP
Stand: