Theme-Werkbank: das Widget per customization-API umfärben
Das Messaging-Widget muss nicht nach Baukasten aussehen. Die Customization-API färbt jedes Element zur Laufzeit um, vom Header bis zur Sprechblase:
zE('messenger:set', 'customization', {
theme: {
primary: '#f0b90a',
onPrimary: '#1e1e20',
background: '#f2eee6',
onBackground: '#1e1e20',
// … insgesamt 17 Properties
},
});
Die 17 Theme-Properties
Jede Fläche hat eine Partnerfarbe mit on…-Präfix für Text und Icons darauf:
primary/onPrimary– Header und Hauptelementebackground/onBackground– Widget-Hintergrundmessage/onMessage– Sprechblase der KundschaftbusinessMessage/onBusinessMessage– Antworten von Bot und Teamaction/onAction/onSecondaryAction– ButtonsconversationListBackground/onConversationListBackground– Konversationslistenotify/onNotifyunderror/onError– Systemmeldungen
Nicht gesetzte Werte fallen auf die Standards aus dem Admin Center zurück. Ein Teil-Theme mit vier Zeilen reicht für einen Markenauftritt. Alle Werte sind gewöhnliche CSS-Farben, die Property-Namen sind case-sensitiv.
Kontrast automatisch wählen
Die Werkbank wählt die on…-Farben automatisch: Relativluminanz nach WCAG ausrechnen, dann gewinnt die Variante mit dem höheren Kontrast. Der Kern bleibt klein:
function luminanz(hex) {
const kanal = (i) => {
const c = parseInt(hex.slice(i, i + 2), 16) / 255;
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
};
return 0.2126 * kanal(1) + 0.7152 * kanal(3) + 0.0722 * kanal(5);
}
function kontrast(a, b) {
const [hell, dunkel] = [luminanz(a), luminanz(b)].sort((x, y) => y - x);
return (hell + 0.05) / (dunkel + 0.05);
}
const textFarbe = kontrast(hintergrund, '#1e1e20') >= kontrast(hintergrund, '#f2eee6')
? '#1e1e20'
: '#f2eee6';
Damit kann niemand ein unlesbares Widget zusammenklicken, egal welche Grundfarbe gewählt wird.
Stolperstein 1: die tote zE-Referenz
Das Zendesk-Snippet stellt sofort ein window.zE bereit, aber das ist nur eine Warteschlange. Nach dem Boot ersetzt das Widget diese Funktion durch die echte API. Wer sich zE früh in eine Variable gelegt hat, ruft danach ins Leere: kein Fehler, keine Warnung, keine Wirkung.
// ❌ Referenz wird nach dem Boot ungültig:
const zE = window.zE;
später(() => zE('messenger:set', 'customization', …)); // verpufft
// ✅ window.zE bei jedem Aufruf frisch auflösen:
const ze = (...args) => window.zE?.(...args);
Stolperstein 2: contentScale steht in der Doku und tut nichts
Die Doku beschreibt eine contentScale-Option (50–200 %). Stand Juli 2026 ignoriert das ausgelieferte Widget sie vollständig: als Faktor, als Prozentwert, live gesetzt oder vor dem Render, keine Wirkung, kein Fehler. Deshalb hat die Werkbank keinen Skalierungs-Regler. Wenn Zendesk die Option scharf schaltet, kommt er zurück.
Bonus fürs Protokoll: Ein zweiter render-Aufruf dupliziert das Widget im Container. Es gibt kein Un-Render: Render-Optionen ändern heisst Seite neu laden.