Technische Einzelheiten
Protokoll, Fehlercodes, Barrierefreiheit und der Stand hinter jeder Zusage.
Diese Seite ist für die, die es genau wissen wollen. Alles hier ist gemessen oder aus dem Quelltext abgelesen — nichts davon ist geschätzt.
Wie das Widget lädt
Zwei Stufen. Zuerst kommt ein kleiner Ladeteil, der den Knopf zeichnet und sonst nichts tut. Der eigentliche Chat wird erst nachgeladen, wenn einer von fünf Auslösern greift — Klick auf den Knopf, ein Befehl aus der Seite, eine Regel, Scrollen, oder ein Zeitgeber.
Das hat einen Grund: die meisten Besucher öffnen den Chat nie. Für sie soll nichts geladen werden, was sie nicht brauchen.
- Ladeteil: 2,83 kB (brotli)
- Ganzes Widget: 59,2 kB gzip, 51,8 kB brotli
- Bis der Knopf steht: 11–21 ms
- Layoutverschiebung: 0,0000 — der Platz steht fest, bevor etwas erscheint
Zum Vergleich, ebenfalls nachgemessen: der Ladeteil von Crisp liegt bei 2 876 B, der von Intercom bei 3 161 B. Wir liegen mit 2 827 B gleichauf, nicht um Größenordnungen darunter. Wer etwas anderes behauptet, hat nicht gemessen.
Es stört eure Seite nicht
Das Widget lebt in einem geschlossenen Shadow DOM. Eure Stile erreichen es
nicht, seine Stile erreichen eure Seite nicht — auch dann nicht, wenn ihr
* { box-sizing: border-box } setzt oder ein CSS-Framework benutzt, das alles
umdefiniert.
Es läuft unter strikter Content-Security-Policy ohne eine einzige Meldung
in der Konsole: kein eval, keine nachgeladene Schriftart, kein Zählpixel.
Seine Stile setzt es über konstruierbare Stylesheets, und die fallen nicht
unter style-src. Knopf, Chatfenster, Produkt-Touren und die
Agentenkonsole auf eurer Seite brauchen deshalb kein unsafe-inline —
nachgemessen unter style-src 'self' und sogar unter style-src 'none': null
Verstöße, voll gestaltet. Gemessen im aktuellen Chromium; ältere Browser ohne
konstruierbare Stylesheets (etwa Safari vor 16.4) nehmen einen Rückfall über
ein <style>-Element, den eine strikte Richtlinie sperrt.
Null Anfragen an fremde Server. Alles kommt von der Adresse, unter der ihr das Widget einbindet.
Das Protokoll
Die Verbindung läuft über WebSocket, das Protokoll ist versioniert und kennt 25 Fehlercodes — jeder mit einer festgelegten Antwort des Clients (wiederholen, nicht wiederholen, Verbindung schließen). Ein Fehler, der nicht in der Liste steht, wird wie „nicht wiederholen" behandelt: lieber eine Nachricht zu wenig als eine Endlosschleife.
Wiederverbinden mit wachsendem Abstand. Bricht die Verbindung ab, wandern Nachrichten in einen Puffer und gehen raus, sobald es wieder geht. Jede Nachricht trägt eine Kennung; der Server erkennt Wiederholungen und legt sie nicht zweimal ab.
Barrierefreiheit
Gebaut gegen WCAG 2.2 AA:
- Fokusfalle im offenen Fenster, ESC schließt, der Fokus geht dorthin zurück, wo er vorher war
- Neue Nachrichten werden über
aria-liveangesagt - Der Kontrast von Text zu Fläche wird nachgerechnet, nicht angenommen — siehe unten
- Bedienbar mit der Tastatur allein, sichtbarer Fokusring
Der Kontrast wird gerechnet
Ihr gebt eine Farbe an. Die Fläche bekommt genau diese Farbe. Die Schrift darauf wird so lange verschoben, bis sie das Verhältnis 4,5:1 erreicht — die Anforderung aus WCAG für normalen Text.
Nachgemessen über 178 Farben in zwei Themen und drei Paarungen, also 1 068 Messpunkte: kein einziger unter 4,5:1, der schlechteste Wert 4,50:1.
Das ist der Unterschied zu anderen Anbietern: dort lässt sich ein Widget so einstellen, dass niemand es mehr lesen kann.
Persönliche Daten
Maskiert wird an zwei Stellen — im Browser des Besuchers, bevor etwas den Rechner verlässt, und noch einmal auf dem Server, bevor etwas gespeichert wird. Erkannt werden Kartennummern (mit Luhn-Prüfung), IBANs, E-Mail-Adressen, Telefonnummern und lange Ziffernfolgen.
Zwei Stellen, weil eine nicht genügt: die im Browser lässt sich abschalten, die auf dem Server sieht nur, was ankommt.
Regeln
Wann sich das Widget meldet, steht in einer deklarativen Regelliste — nicht in einer Bedingung im Code. Fünf Regeln sind vorgegeben (Wut-Klick, JavaScript-Fehler, Kaufabsicht, Ausstiegsabsicht, Untätigkeit), eigene lassen sich ergänzen.
Der Unterschied ist praktisch: eine Regel ändern heißt eine Zeile ändern, nicht eine Auslieferung.
Integrationen
Webhook und Slack sind fertig. Für alle weiteren steht der Anbieter im Code, die meisten sind aber noch nie gegen den echten Dienst gelaufen.
Jede Integration läuft über eine Warteschlange mit Sicherung: hängt ein Drittdienst, wird er nach mehreren Fehlversuchen für eine Weile übersprungen. Eine Chat-Nachricht wird davon nie aufgehalten — das ist die wichtigste Regel in dieser Schicht.
Was noch nicht fertig ist
Damit niemand es beim Einbauen herausfindet:
- Die MousePlayer-Brücke fragt aktiv nach, weil MousePlayer die vereinbarten Ereignisse heute noch nicht von sich aus sendet.
- REST-API und Agentenoberfläche sind angefangen, nicht fertig.
Stand: