Chat einbetten und eigene Widgets¶
Es gibt im CLYE AI mehrere Wege, einen Chat außerhalb der normalen Oberfläche zu nutzen. Welcher Weg sinnvoll ist, hängt davon ab, wie viel Kontrolle du über Design, Zugriff und Verhalten brauchst.
Überblick¶
| Variante | Geeignet für | Zugriff | Eigener UI-Aufwand |
|---|---|---|---|
| Öffentliches Script-Widget | Website, Landingpage, einfache Einbindung | öffentlich freigegebener Assistent | sehr gering |
| Widget per iFrame | Portale, Login-geschützte Bereiche, kontrollierte Freigabe | JWT oder Assistant Access Link | gering |
| Eigenes Widget mit AI SDK | volle UI-Kontrolle, eigenes Frontend, Produktintegration | meist Assistant Access Link | hoch |
Als Grundregel gilt:
- Nutze die integrierten Widgets, wenn du schnell einbettbar bleiben willst.
- Nutze Assistant Access Links, wenn Zugriff, Filter und Features serverseitig kontrolliert werden sollen.
- Nutze das AI SDK, wenn du das komplette Frontend selbst bauen willst.
Integrierte Widgets¶
Im Bot-Frontend wird ein eigenständiges Bundle widget.js gebaut. Dieses Bundle kann direkt in fremde Websites geladen werden und registriert mehrere Custom Elements.
1. Öffentliches Chat-Widget¶
Für die meisten Websites ist das die einfachste Variante:
<script type="module" src="https://bot.clye.app/widget.js"></script>
<clye-bot-chat bot-id="123"></clye-bot-chat>
Dieses Element rendert die bekannte Chat-Bubble und hängt sie an den body der Seite. Im Code ist das die empfohlene öffentliche Standard-Einbindung.
Wichtige Attribute:
bot-id: numerische ID des Assistentenside:"left"oder"right"blend-mode: z. B."normal"oder"difference"dark: optional für dunkle Darstellungdomain: falls das Widget gegen eine andere Bot-Domain sprechen sollstyle-url: alternative CSS-Datei für die Bubble
Praktisch heißt das: Wenn eure Seite eigenes HTML erlaubt, reicht oft schon das Script plus das Element.
2. Direkte Bubble-Komponenten¶
Zusätzlich registriert widget.js niedrigere Bausteine:
clye-bot-bubbleclye-bot-bubble-open-shadow
Die beiden Varianten sind nützlich, wenn du die Bubble gezielter kontrollieren willst – zum Beispiel wenn du sie direkt in eine bestimmte Stelle im DOM einbetten willst, anstatt sie über das Portal-Verhalten von clye-bot-chat an den body anzuhängen.
Der Unterschied liegt im Shadow DOM:
clye-bot-bubblenutzt ein geschlossenes Shadow DOM (empfohlen, Styles sind isoliert)clye-bot-bubble-open-shadownutzt ein offenes Shadow DOM (nützlich, wenn du per JavaScript von außen in das Shadow DOM zugreifen musst)
<script type="module" src="https://bot.clye.app/widget.js"></script>
<clye-bot-bubble bot-id="123" side="right"></clye-bot-bubble>
Wichtige Attribute:
| Attribut | Typ | Beschreibung |
|---|---|---|
bot-id |
Zahl | Numerische ID des Assistenten (Pflichtfeld) |
side |
"left" | "right" |
Auf welcher Seite die Bubble erscheint |
dark |
Boolean | Aktiviert die dunkle Darstellung |
style-url |
String | Pfad zu einer alternativen CSS-Datei |
domain |
String | Alternative Bot-Domain |
Der Unterschied zu clye-bot-chat: clye-bot-chat ist ein Portal-Element, das die Bubble selbst erzeugt und direkt an den document.body anhängt. clye-bot-bubble hingegen rendert an der Stelle im DOM, wo du das Element platzierst.
blend-mode wird bei clye-bot-bubble nicht als HTML-Attribut unterstützt. Für blend-mode nutze clye-bot-chat.
3. Frage-Widget¶
Für vordefinierte Einstiegsfragen gibt es zusätzlich:
<script type="module" src="https://bot.clye.app/widget.js"></script>
<clye-bot-question
bot-id="123"
label="Schnellstart"
question="Wie kann ich helfen?"
bot-question="Erkläre kurz, was du kannst."
></clye-bot-question>
Wichtige Attribute:
bot-idlabelquestionbot-questionanswersals JSONdomain
Das ist sinnvoll, wenn nicht sofort ein vollständiger Chat erscheinen soll, sondern erst ein klarer Einstiegspunkt.
4. Web-Component-Konstruktoren aus dem Widget-Bundle¶
Das Bundle legt zusätzlich window.clyeBot an. Dort liegen die Web-Component-Konstruktoren für alle registrierten Elemente:
| Eigenschaft | Registriert als | Beschreibung |
|---|---|---|
window.clyeBot.Chat |
(nicht vorregistriert) | Vollständige Chat-Ansicht ohne Bubble-Wrapper. Muss manuell registriert werden. |
window.clyeBot.Bubble |
clye-bot-bubble |
Identisch mit dem gleichnamigen Custom Element |
window.clyeBot.Question |
clye-bot-question |
Identisch mit dem gleichnamigen Custom Element |
window.clyeBot.Chat ist der einzige Konstruktor, der nicht automatisch als Custom Element registriert wird. Das gibt dir die Möglichkeit, ihn unter einem eigenen Tag-Namen einzubinden:
<script type="module">
import "https://bot.clye.app/widget.js";
// eigener Tag-Name, weil clye-bot-chat bereits ein Portal-Element ist
customElements.define("mein-chat", window.clyeBot.Chat);
</script>
<mein-chat bot-id="123"></mein-chat>
window.clyeBot.Chat rendert die Chat-Oberfläche direkt (ohne Bubble und Floating-Button). Unterstützte Attribute: bot-id (Zahl), domain (String).
Widget per iFrame¶
Wenn du den Chat als komplette, kontrollierte Oberfläche einbetten willst, bleibt das iFrame-Widget der stabilste Weg:
<iframe
src="https://dein-hub.example/widget/<TOKEN>"
style="width: 100%; height: 600px; border: none;"
allow="clipboard-write"
></iframe>
Dafür gibt es zwei Token-Varianten:
- JWT-Widget: gut für einfache, kurze Claims wie
botIdundexp - Assistant Access Link: besser für serverseitig erzwungene Filter, Features und längere Payloads
Mehr dazu:
Eigene Chat-Widgets mit AI SDK¶
Wenn du das Frontend komplett selbst bauen willst, ist der relevante Pfad im Bot-Repo die Kombination aus:
@ai-sdk/reactfüruseChataifürDefaultChatTransportPOST /api/chatals Backend-Endpunkt
Genau dieses Muster wird im Bot selbst verwendet, sowohl für eingebettete Chats als auch für normale Chat-Oberflächen.
Wann das sinnvoll ist¶
Ein eigenes Widget mit AI SDK ist sinnvoll, wenn du:
- Design und UX vollständig selbst bestimmen willst
- den Chat in eine bestehende Produktoberfläche integrieren willst
- zusätzliche UI-Elemente wie Tabs, Formulare, Produktdaten oder Prozessschritte kombinieren willst
- nicht an Bubble- oder iFrame-Layout gebunden sein willst
Wichtiger Unterschied zu JWT-Widgets¶
Für eigene AI-SDK-Frontends ist in der Regel der Assistant Access Link der richtige Zugriffspfad.
Der Grund: Das Chat-Backend leitet externe Sitzungen aus assistantAccessToken ab. Dieser Token wird im Request-Body mitgegeben. Das JWT-Widget ist dagegen primär für die Route /widget/{token} gedacht.
Kurz gesagt:
- iFrame auf
/widget/{token}: JWT oder Assistant Access Link möglich - Eigenes Frontend auf
/api/chat: bevorzugt Assistant Access Link verwenden
Minimales React-Beispiel¶
Benötigte Version: Das Beispiel basiert auf AI SDK v5 (ai und @ai-sdk/react in derselben Major-Version, idealerweise beide auf ^5).
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
type Props = {
botId: number;
assistantAccessToken?: string;
};
export function EmbeddedChat({ botId, assistantAccessToken }: Props) {
const chat = useChat({
transport: new DefaultChatTransport({
api: "https://<deine-whitelabel-domain>/api/chat",
body: {
botId,
...(assistantAccessToken ? { assistantAccessToken } : {}),
},
}),
});
return (
<div>
<div>
{chat.messages.map((message) => (
<div key={message.id}>
<strong>{message.role}:</strong> {message.parts?.map((p: any) => p.text).join("")}
</div>
))}
</div>
<form
onSubmit={(event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const text = String(formData.get("message") || "");
if (!text.trim()) return;
chat.sendMessage({ text });
event.currentTarget.reset();
}}
>
<input name="message" placeholder="Nachricht..." />
<button type="submit">Senden</button>
</form>
</div>
);
}
Praxisbeispiel mit öffentlichem Assistenten (für alle freigegeben):
Das Beispiel ist bewusst minimal. In der Praxis wirst du meist noch ergänzen:
- persistente
chatIdpro Session - eigenes Fehler-Handling
- Wiederaufnahme laufender Streams
- Uploads oder Tool-Interaktionen
- eigenes Rendering für strukturierte Antworten und Tool-Calls
Was das Backend erwartet¶
Der Chat-Endpunkt akzeptiert unter anderem:
botIdmessagesodernewMessages- optional
assistantAccessToken - optional
idfür eine persistente Chat-ID
Wenn ein assistantAccessToken gesetzt ist, wird serverseitig daraus eine minimale Widget-Session abgeleitet. Darüber können auch permissionFilter, loginUrl, features.chatHistory und Widget-Kontext aus dem Access Link wirksam werden.
Serverseitige Erzeugung des Access Links¶
Für eigene Widgets sieht der saubere Ablauf so aus:
- Dein Portal oder Backend prüft die Anmeldung des Nutzers.
- Dein Server ruft
POST /api/assistant-linkauf. - Die Antwort liefert
token,urlundjwtPayload. - Dein Frontend verwendet den
tokenalsassistantAccessTokenfürPOST /api/chat.
Damit bleiben Berechtigungen, Filter und Ablaufzeit auf deiner Server-Seite kontrollierbar.
Welche Variante in der Praxis passt¶
Nutze das öffentliche Script-Widget, wenn eine Website schnell einen Assistenten bekommen soll.
Nutze das iFrame-Widget, wenn du die vorhandene Chat-Oberfläche übernehmen und nur kontrolliert einbetten willst.
Nutze ein eigenes AI-SDK-Widget, wenn der Chat Teil eures Produkts werden soll und visuell oder funktional stark an eure Anwendung angepasst werden muss.
Kurz gesagt¶
Die integrierten Widgets decken den schnellen Einbau ab. Für eine kontrollierte externe Nutzung ist meist der Assistant Access Link die beste Grundlage. Wenn du dagegen die Oberfläche selbst besitzen willst, orientiere dich am im Bot bereits verwendeten Muster aus useChat, DefaultChatTransport und POST /api/chat.