Aller au contenu principal

Theming et personnalisation

Mis à jour le 29 juillet 2026

Theming et personnalisation

Un chat générique ne s’intègre pas dans votre produit. Vos utilisateurs voient immédiatement qu’un composant vient d’ailleurs : la police n’est pas la vôtre, le bleu n’est pas votre bleu, les coins sont trop carrés. ChatKit offre pour cette raison un système de theming complet qui adapte chaque aspect visuel à votre charte graphique : couleurs, typographie, espacement, coins arrondis et animations.

Le système de thème

Le theming passe par un objet unique que vous transmettez au ChatProvider. Il regroupe quatre familles de réglages : les couleurs, la typographie, les espacements et les rayons de bordure. Vous ne touchez pas au balisage, vous décrivez une apparence, et tous les composants enfants s’y conforment. C’est la voie à privilégier tant que vos besoins restent dans le cadre prévu.

import { ChatProvider, ChatWindow, MessageInput } from "@openai/chatkit/react";

const monTheme = {
  colors: {
    primary: "#2563EB",        // Bleu principal
    primaryHover: "#1D4ED8",   // Bleu au survol
    background: "#0F172A",     // Fond sombre
    surface: "#1E293B",        // Surface des messages
    text: "#F8FAFC",           // Texte principal
    textSecondary: "#94A3B8",  // Texte secondaire
    border: "#334155",         // Bordures
    userBubble: "#2563EB",     // Bulle utilisateur
    agentBubble: "#1E293B",    // Bulle agent
    inputBackground: "#1E293B",
    inputBorder: "#475569",
  },
  typography: {
    fontFamily: "'Inter', sans-serif",
    fontSize: "14px",
    lineHeight: "1.6",
    messageFontSize: "15px",
  },
  spacing: {
    messagePadding: "12px 16px",
    messageGap: "8px",
    containerPadding: "16px",
  },
  borders: {
    radius: "12px",
    messageRadius: "16px",
    inputRadius: "24px",
  },
};

function ChatDeProduit() {
  return (
    <ChatProvider endpoint="/api/chat" theme={monTheme}>
      <div style={{ height: "100vh", display: "flex", flexDirection: "column" }}>
        <ChatWindow />
        <MessageInput placeholder="Comment puis-je vous aider ?" />
      </div>
    </ChatProvider>
  );
}

Deux détails de cet exemple portent l’essentiel de la lisibilité. La distinction userBubble / agentBubble donne au lecteur un repère instantané sur qui parle, sans avoir à lire le contenu ; conserver un contraste net entre les deux vaut mieux que deux nuances proches et élégantes. Et inputRadius à 24px, plus large que le messageRadius à 16px, transforme la zone de saisie en pilule : elle se détache du flux de messages et signale visuellement « c’est ici que vous écrivez ».

Personnaliser les messages

Quand le thème ne suffit plus — vous voulez un avatar d’agent, un badge « brouillon », une mise en page à deux colonnes — vous reprenez la main sur le rendu d’un message entier via renderMessage. Le composant reçoit le message et décide de tout : alignement, avatar, largeur maximale, couleur de bulle.

import { ChatProvider, ChatWindow, MessageInput } from "@openai/chatkit/react";

function MessagePersonnalise({ message, isUser }) {
  return (
    <div
      style={{
        display: "flex",
        justifyContent: isUser ? "flex-end" : "flex-start",
        marginBottom: "8px",
      }}
    >
      {!isUser && (
        <div style={{
          width: "32px",
          height: "32px",
          borderRadius: "50%",
          background: "#2563EB",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          marginRight: "8px",
          fontSize: "14px",
        }}>
          AI
        </div>
      )}
      <div
        style={{
          maxWidth: "70%",
          padding: "12px 16px",
          borderRadius: "16px",
          background: isUser ? "#2563EB" : "#1E293B",
          color: "#F8FAFC",
        }}
      >
        {message.content}
      </div>
    </div>
  );
}

function Chat() {
  return (
    <ChatProvider endpoint="/api/chat">
      <ChatWindow renderMessage={(msg) => (
        <MessagePersonnalise message={msg} isUser={msg.role === "user"} />
      )} />
      <MessageInput />
    </ChatProvider>
  );
}

Remarquez le maxWidth: "70%" : sans cette limite, une réponse longue s’étale sur toute la largeur de l’écran et devient pénible à lire sur un moniteur large. L’avatar, lui, n’apparaît que côté agent — l’utilisateur sait qui il est, l’afficher des deux côtés ne fait qu’alourdir la colonne.

Mode sombre et mode clair

Le thème n’est pas figé au montage : c’est une simple prop, donc vous pouvez la remplacer à chaud. Le cas classique est le bouton de bascule sombre/clair de votre application, dont l’état pilote aussi le chat. En pratique vous branchez cette valeur sur votre store global ou sur prefers-color-scheme plutôt que sur un état local, pour que l’utilisateur ne voie jamais un chat sombre dans une interface claire.

import { useState } from "react";

const themeSombre = {
  colors: {
    background: "#0F172A",
    surface: "#1E293B",
    text: "#F8FAFC",
    primary: "#3B82F6",
  },
};

const themeClair = {
  colors: {
    background: "#FFFFFF",
    surface: "#F1F5F9",
    text: "#0F172A",
    primary: "#2563EB",
  },
};

function ChatAvecTheme() {
  const [modeNuit, setModeNuit] = useState(true);

  return (
    <ChatProvider endpoint="/api/chat" theme={modeNuit ? themeSombre : themeClair}>
      <button onClick={() => setModeNuit(!modeNuit)}>
        {modeNuit ? "Mode clair" : "Mode sombre"}
      </button>
      <ChatWindow />
      <MessageInput />
    </ChatProvider>
  );
}

Personnaliser la zone de saisie

La zone de saisie est souvent le premier point de contact visuel, et son paramétrage relève autant de l’ergonomie que du style. Le placeholder oriente la conversation : « Posez votre question sur nos services… » produit des messages bien plus exploitables qu’un « Écrivez ici » neutre. maxLength associé à showCharCount évite qu’un utilisateur colle trois pages de log sans comprendre pourquoi rien ne part. submitOnEnter accélère les échanges courts, et showAttachButton à false retire une affordance que votre backend ne saurait pas honorer — rien n’est plus frustrant qu’un trombone qui n’aboutit à rien.

<MessageInput
  placeholder="Posez votre question sur nos services..."
  maxLength={2000}
  showCharCount={true}
  submitOnEnter={true}
  showAttachButton={false}
  style={{
    borderTop: "1px solid #334155",
    padding: "16px",
  }}
/>

CSS personnalisé

Pour un contrôle total, ChatKit expose des classes CSS stables sur lesquelles vous pouvez écrire vos propres règles. C’est la porte de sortie quand le thème n’atteint pas ce que vous visez : un dégradé sur les bulles de l’agent, une bulle utilisateur au coin inférieur droit rogné pour évoquer une pointe de bulle, un anneau de focus conforme à votre design system. Réservez cette voie aux finitions, car vous vous couplez alors à des noms de classes internes plutôt qu’à une API de thème.

/* styles/chatkit-custom.css */

/* Conteneur principal */
.chatkit-container {
  font-family: 'Inter', sans-serif;
}

/* Messages de l'agent */
.chatkit-message--agent {
  background: linear-gradient(135deg, #1E293B, #0F172A);
  border: 1px solid rgba(59, 130, 246, 0.1);
}

/* Messages de l'utilisateur */
.chatkit-message--user {
  background: #2563EB;
  border-radius: 16px 16px 4px 16px;
}

/* Zone de saisie */
.chatkit-input {
  background: #1E293B;
  border: 1px solid #475569;
  border-radius: 24px;
  transition: border-color 0.2s;
}

.chatkit-input:focus-within {
  border-color: #3B82F6;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
}

/* Indicateur de chargement */
.chatkit-typing-indicator {
  color: #94A3B8;
}

/* Bouton d'envoi */
.chatkit-send-button {
  background: #2563EB;
  border-radius: 50%;
  width: 36px;
  height: 36px;
}

Prenez le temps de vérifier le résultat sur un écran de téléphone avant de conclure : un maxWidth de 70 % et un padding de 16px qui respirent sur un ordinateur portable deviennent vite étriqués sur 375 pixels de large.

Points clés à retenir

  • Le système de thème contrôle couleurs, typographie, espacement et bordures
  • Les composants de message personnalisés permettent un rendu sur mesure
  • Le thème peut changer dynamiquement (mode sombre/clair)
  • Les classes CSS de ChatKit permettent un contrôle fin au pixel
  • Adaptez le placeholder et les options de la zone de saisie à votre contexte