Les widgets sont les conteneurs et les composants fournis avec ChatKit. Pour personnaliser entièrement ChatKit dans votre produit, vous pouvez utiliser des widgets prêts à l’emploi, adapter des modèles ou concevoir vos propres widgets.

Concevez rapidement des widgets
Utilisez le Widget Builder de ChatKit Studio pour essayer différentes dispositions de cartes et de lignes de liste, et prévisualiser les composants. Une fois la mise en page choisie, copiez le JSON généré dans votre intégration et servez-le depuis votre backend.
Importez des ressources
Importez des ressources pour adapter l’apparence des widgets ChatKit à celle de votre produit. Pour que ChatKit puisse les utiliser, votre backend doit héberger les fichiers et les images importés avant que vous y fassiez référence dans un message. Consultez le guide d’importation du SDK Python pour un exemple d’implémentation de référence.
Les widgets ChatKit peuvent afficher des informations contextuelles, des raccourcis et des cartes interactives directement dans la conversation. Lorsqu’un utilisateur clique sur un bouton de widget, votre application reçoit les données d’une action personnalisée, ce qui vous permet d’y répondre depuis votre backend.
Traitez les actions sur votre serveur
Les actions des widgets permettent aux utilisateurs de déclencher l’exécution de code depuis l’interface. Vous pouvez associer des actions à différents événements sur les nœuds d’un widget, par exemple à un clic sur un bouton, puis les traiter dans votre intégration côté serveur ou côté client.
Interceptez les événements des widgets avec la fonction de rappel onAction de WidgetsOption ou avec le hook React équivalent. Transmettez les données de chaque action à votre backend pour qu’il la traite.
chatkit.setOptions({
widgets: {
async onAction(action, item) {
await fetch("/api/widget-action", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action, itemId: item.id }),
});
},
},
});Vous cherchez un exemple complet côté serveur ? La documentation du SDK Python de ChatKit vous guide pas à pas, du début à la fin.
Pour en savoir plus, consultez la documentation sur les actions.
Référence
Nous vous recommandons de commencer par les outils de conception visuelle présentés ci-dessus. La suite de cette documentation explique le fonctionnement des widgets et détaille les options disponibles.
Chaque widget se compose d’un seul conteneur (WidgetRoot), qui regroupe plusieurs composants (WidgetNode).
Conteneurs (WidgetRoot)
Les conteneurs offrent des fonctionnalités spécifiques, comme l’affichage d’un texte indiquant l’état du widget ou de boutons pour les actions principales.
-
Card – Conteneur qui délimite une zone pour les widgets. Les champs
status,confirmetcancelpermettent d’afficher des indicateurs d’état et des boutons d’action sous le widget.children: list[WidgetNode]size: “sm” | “md” | “lg” | “full” (par défaut : “md”)padding: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)background: str |{ dark: str, light: str }| Nonestatus:{ text: str, favicon?: str }|{ text: str, icon?: str }| Nonecollapsed: bool | NoneasForm: bool | Noneconfirm:{ label: str, action: ActionConfig }| Nonecancel:{ label: str, action: ActionConfig }| Nonetheme: “light” | “dark” | Nonekey: str | None
-
ListView – Affiche une liste verticale dont chaque élément est un
ListViewItem.children: list[ListViewItem]limit: int | “auto” | Nonestatus:{ text: str, favicon?: str }|{ text: str, icon?: str }| Nonetheme: “light” | “dark” | Nonekey: str | None
Composants (WidgetNode)
ChatKit prend en charge les types de widgets suivants. Vous pouvez aussi parcourir les composants et les essayer dans un éditeur interactif depuis la section Composants du Widget Builder.
-
Badge – Petit libellé qui indique un état ou affiche des métadonnées.
label: strcolor: “secondary” | “success” | “danger” | “warning” | “info” | “discovery” | Nonevariant: “solid” | “soft” | “outline” | Nonepill: bool | Nonesize: “sm” | “md” | “lg” | Nonekey: str | None
-
Box – Conteneur de mise en page flexible dont vous pouvez régler l’orientation, l’espacement et le style.
children: list[WidgetNode] | Nonedirection: “row” | “column” | Nonealign: “start” | “center” | “end” | “baseline” | “stretch” | Nonejustify: “start” | “center” | “end” | “stretch” | “between” | “around” | “evenly” | Nonewrap: “nowrap” | “wrap” | “wrap-reverse” | Noneflex: int | str | Noneheight: float | str | Nonewidth: float | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | Nonesize: float | str | NoneminSize: int | str | NonemaxSize: int | str | Nonegap: int | str | Nonepadding: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)margin: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)border: int |dict[str, Any]| None (bordure commune :{ size: int, color?: str|{ dark: str, light: str }, style?: “solid” | “dashed” | “dotted” | “double” | “groove” | “ridge” | “inset” | “outset” }per-side:{ top?: int|dict, right?: int|dict, bottom?: int|dict, left?: int|dict, x?: int|dict, y?: int|dict })radius: “2xs” | “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | “4xl” | “full” | “100%” | “none” | Nonebackground: str |{ dark: str, light: str }| NoneaspectRatio: float | str | Nonekey: str | None
-
Row – Dispose les éléments enfants horizontalement.
children: list[WidgetNode] | Nonegap: int | str | Nonepadding: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)align: “start” | “center” | “end” | “baseline” | “stretch” | Nonejustify: “start” | “center” | “end” | “stretch” | “between” | “around” | “evenly” | Noneflex: int | str | Noneheight: float | str | Nonewidth: float | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | Nonesize: float | str | NoneminSize: int | str | NonemaxSize: int | str | Nonemargin: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)border: int | dict[str, Any] | None (bordure commune :{ size: int, color?: str | { dark: str, light: str }, style?: "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "inset" | "outset" }par côté :{ top?: int|dict, right?: int|dict, bottom?: int|dict, left?: int|dict, x?: int|dict, y?: int|dict })radius: “2xs” | “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | “4xl” | “full” | “100%” | “none” | Nonebackground: str |{ dark: str, light: str }| NoneaspectRatio: float | str | Nonekey: str | None
-
Col – Dispose les éléments enfants verticalement.
children: list[WidgetNode] | Nonegap: int | str | Nonepadding: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)align: “start” | “center” | “end” | “baseline” | “stretch” | Nonejustify: “start” | “center” | “end” | “stretch” | “between” | “around” | “evenly” | Nonewrap: “nowrap” | “wrap” | “wrap-reverse” | Noneflex: int | str | Noneheight: float | str | Nonewidth: float | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | Nonesize: float | str | NoneminSize: int | str | NonemaxSize: int | str | Nonemargin: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)border: int | dict[str, Any] | None (bordure commune :{ size: int, color?: str | { dark: str, light: str }, style?: "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "inset" | "outset" }par côté :{ top?: int|dict, right?: int|dict, bottom?: int|dict, left?: int|dict, x?: int|dict, y?: int|dict })radius: “2xs” | “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | “4xl” | “full” | “100%” | “none” | Nonebackground: str |{ dark: str, light: str }| NoneaspectRatio: float | str | Nonekey: str | None
-
Button – Bouton d’action personnalisable.
submit: bool | Nonestyle: “primary” | “secondary” | Nonelabel: stronClickAction: ActionConfigiconStart: str | NoneiconEnd: str | Nonecolor: “primary” | “secondary” | “info” | “discovery” | “success” | “caution” | “warning” | “danger” | Nonevariant: “solid” | “soft” | “outline” | “ghost” | Nonesize: “3xs” | “2xs” | “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | Nonepill: bool | Noneblock: bool | Noneuniform: bool | NoneiconSize: “sm” | “md” | “lg” | “xl” | “2xl” | Nonekey: str | None
-
Caption – Texte complémentaire affiché en plus petits caractères.
value: strsize: “sm” | “md” | “lg” | Noneweight: “normal” | “medium” | “semibold” | “bold” | NonetextAlign: “start” | “center” | “end” | Nonecolor: str |{ dark: str, light: str }| Nonetruncate: bool | NonemaxLines: int | Nonekey: str | None
-
DatePicker – Champ de saisie de date avec calendrier déroulant.
onChangeAction: ActionConfig | Nonename: strmin: datetime | Nonemax: datetime | Noneside: “top” | “bottom” | “left” | “right” | Nonealign: “start” | “center” | “end” | Noneplaceholder: str | NonedefaultValue: datetime | Nonevariant: “solid” | “soft” | “outline” | “ghost” | Nonesize: “3xs” | “2xs” | “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | Nonepill: bool | Noneblock: bool | Noneclearable: bool | Nonedisabled: bool | Nonekey: str | None
-
Divider – Séparateur horizontal ou vertical.
spacing: int | str | Nonecolor: str |{ dark: str, light: str }| Nonesize: int | str | Noneflush: bool | Nonekey: str | None
-
Icon – Affiche l’icône correspondant au nom indiqué.
name: strcolor: str |{ dark: str, light: str }| Nonesize: “xs” | “sm” | “md” | “lg” | “xl” | Nonekey: str | None
-
Image – Affiche une image. Vous pouvez en régler le style, l’ajustement au cadre et la position.
size: int | str | Noneheight: int | str | Nonewidth: int | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | NoneminSize: int | str | NonemaxSize: int | str | Noneradius: “2xs” | “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | “4xl” | “full” | “100%” | “none” | Nonebackground: str |{ dark: str, light: str }| Nonemargin: int | str | dict[str, int | str] | None (clés :top,right,bottom,left,x,y)aspectRatio: float | str | Noneflex: int | str | Nonesrc: stralt: str | Nonefit: “none” | “cover” | “contain” | “fill” | “scale-down” | Noneposition: “center” | “top” | “bottom” | “left” | “right” | “top left” | “top right” | “bottom left” | “bottom right” | Noneframe: bool | Noneflush: bool | Nonekey: str | None
-
ListView – Affiche une liste verticale d’éléments.
children: list[ListViewItem] | Nonelimit: int | “auto” | Nonestatus: dict[str, Any] | None (structure :{ text: str, favicon?: str })theme: “light” | “dark” | Nonekey: str | None
-
ListViewItem – Élément d’une liste
ListViewauquel vous pouvez associer une action.children: list[WidgetNode] | NoneonClickAction: ActionConfig | Nonegap: int | str | Nonealign: “start” | “center” | “end” | “baseline” | “stretch” | Nonekey: str | None
-
Markdown – Affiche du texte mis en forme en Markdown et prend en charge les mises à jour en continu.
value: strstreaming: bool | Nonekey: str | None
-
Select – Liste déroulante permettant de sélectionner une seule option.
options: list[dict[str, str]] (pour chaque option :{ label: str, value: str })onChangeAction: ActionConfig | Nonename: strplaceholder: str | NonedefaultValue: str | Nonevariant: “solid” | “soft” | “outline” | “ghost” | Nonesize: “3xs” | “2xs” | “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | Nonepill: bool | Noneblock: bool | Noneclearable: bool | Nonedisabled: bool | Nonekey: str | None
-
Spacer – Réserve un espace vide de taille variable dans la mise en page.
minSize: int | str | Nonekey: str | None
-
Text – Affiche du texte brut (utilisez
Markdownpour le rendu Markdown). Prend en charge les mises à jour en continu.value: strcolor: str |{ dark: str, light: str }| Nonewidth: float | str | Nonesize: “xs” | “sm” | “md” | “lg” | “xl” | Noneweight: “normal” | “medium” | “semibold” | “bold” | NonetextAlign: “start” | “center” | “end” | Noneitalic: bool | NonelineThrough: bool | Nonetruncate: bool | NoneminLines: int | NonemaxLines: int | Nonestreaming: bool | Noneeditable: bool | dict[str, Any] | None (pour un dictionnaire :{ name: str, autoComplete?: str, autoFocus?: bool, autoSelect?: bool, allowAutofillExtensions?: bool, required?: bool, placeholder?: str, pattern?: str })key: str | None
-
Title – Affiche un titre bien visible.
value: strsize: “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | “4xl” | “5xl” | Noneweight: “normal” | “medium” | “semibold” | “bold” | NonetextAlign: “start” | “center” | “end” | Nonecolor: str |{ dark: str, light: str }| Nonetruncate: bool | NonemaxLines: int | Nonekey: str | None
-
Form – Conteneur de mise en page qui peut déclencher une action à l’envoi du formulaire.
onSubmitAction: ActionConfigchildren: list[WidgetNode] | Nonealign: “start” | “center” | “end” | “baseline” | “stretch” | Nonejustify: “start” | “center” | “end” | “stretch” | “between” | “around” | “evenly” | Noneflex: int | str | Nonegap: int | str | Noneheight: float | str | Nonewidth: float | str | NoneminHeight: int | str | NoneminWidth: int | str | NonemaxHeight: int | str | NonemaxWidth: int | str | Nonesize: float | str | NoneminSize: int | str | NonemaxSize: int | str | Nonepadding: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)margin: float | str | dict[str, float | str] | None (clés :top,right,bottom,left,x,y)border: int | dict[str, Any] | None (bordure commune :{ size: int, color?: str | { dark: str, light: str }, style?: "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "inset" | "outset" }par côté :{ top?: int|dict, right?: int|dict, bottom?: int|dict, left?: int|dict, x?: int|dict, y?: int|dict })radius: “2xs” | “xs” | “sm” | “md” | “lg” | “xl” | “2xl” | “3xl” | “4xl” | “full” | “100%” | “none” | Nonebackground: str |{ dark: str, light: str }| Nonekey: str | None
-
Transition – Enveloppe un contenu qui peut être animé.
children: WidgetNode | Nonekey: str | None