> ## Documentation Index
> Fetch the complete documentation index at: https://www.mintlify.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Widget Mintlify

> Installez et configurez le widget Mintlify pour intégrer l'assistant IA entraîné sur votre contenu dans n'importe quel site web ou application web.

export const AssistantWidgetPlayground = ({children, CodeBlockComponent}) => {
  const EXAMPLE_WIDGET_ID = "YOUR_WIDGET_ID";
  const EMBED_URL = "https://cdn.jsdelivr.net/npm/@mintlify/assistant-widget@0.0/dist/browser/embed.js";
  const PREVIEW_READY_MESSAGE = "mintlify-assistant-playground:ready";
  const PREVIEW_UPDATE_MESSAGE = "mintlify-assistant-playground:update";
  const PREVIEW_STATE_MESSAGE = "mintlify-assistant-playground:state";
  const SUPPORT_EMAIL = "hi@mintlify.com";
  const STARTER_QUESTIONS = ["How do I get started with Mintlify?", "How do I customize my docs?", "How do I deploy my docs?"];
  const VARIANT_OPTIONS = [{
    value: "widget",
    label: "Widget"
  }, {
    value: "modal",
    label: "Modal"
  }, {
    value: "panel",
    label: "Panel"
  }];
  const THEME_OPTIONS = [{
    value: "system",
    label: "System"
  }, {
    value: "light",
    label: "Light"
  }, {
    value: "dark",
    label: "Dark"
  }];
  const SIDE_OPTIONS = [{
    value: "top",
    label: "Top"
  }, {
    value: "bottom",
    label: "Bottom"
  }, {
    value: "left",
    label: "Left"
  }, {
    value: "right",
    label: "Right"
  }, {
    value: "inline-start",
    label: "Inline start"
  }, {
    value: "inline-end",
    label: "Inline end"
  }];
  const ALIGN_OPTIONS = [{
    value: "start",
    label: "Start"
  }, {
    value: "center",
    label: "Center"
  }, {
    value: "end",
    label: "End"
  }];
  const INSTALL_OPTIONS = [{
    value: "html",
    label: "HTML"
  }, {
    value: "next",
    label: "Next.js"
  }];
  const [installTarget, setInstallTarget] = useState("html");
  const [variant, setVariant] = useState("widget");
  const [theme, setTheme] = useState("system");
  const [accent, setAccent] = useState("#16a34a");
  const [radius, setRadius] = useState(18);
  const [side, setSide] = useState("bottom");
  const [align, setAlign] = useState("end");
  const [trackEvents, setTrackEvents] = useState(false);
  const [reportErrors, setReportErrors] = useState(false);
  const [previewHostReady, setPreviewHostReady] = useState(false);
  const [previewUrl, setPreviewUrl] = useState(null);
  const [previewStatus, setPreviewStatus] = useState("loading");
  const previewRef = useRef(null);
  const previewHostRef = useRef(null);
  useEffect(() => {
    const pageMatch = window.location.pathname.replace(/\/$/, "").match(/^(.*?)(\/[a-z]{2}(?:-[A-Za-z]{2,4})?)?\/assistant\/widget$/);
    const basePath = pageMatch?.[1] ?? "";
    const locale = pageMatch?.[2] ?? "";
    const mode = document.documentElement.classList.contains("dark") ? "dark" : "light";
    setPreviewUrl(`${basePath}/_minimal${locale}/assistant/widget-preview?mode=${mode}`);
  }, []);
  useEffect(() => {
    const removeRootWidget = () => {
      const rootWidget = document.querySelector("body > mintlify-assistant");
      if (!rootWidget) return false;
      const destroyPromise = window.MintlifyAssistant?.destroy();
      void destroyPromise?.catch(() => {});
      rootWidget.remove();
      return true;
    };
    const rootWidgetObserver = new MutationObserver(removeRootWidget);
    removeRootWidget();
    rootWidgetObserver.observe(document.body, {
      childList: true
    });
    return () => rootWidgetObserver.disconnect();
  }, []);
  useEffect(() => {
    const host = previewHostRef.current;
    if (!host) return undefined;
    const markReady = height => {
      if (height > 0) setPreviewHostReady(true);
    };
    markReady(host.getBoundingClientRect().height);
    if (typeof ResizeObserver === "undefined") {
      setPreviewHostReady(true);
      return undefined;
    }
    const observer = new ResizeObserver(entries => {
      markReady(entries[0]?.contentRect.height ?? 0);
    });
    observer.observe(host);
    return () => observer.disconnect();
  }, []);
  const classNames = (...classes) => classes.filter(Boolean).join(" ");
  const renderSegmentedControl = ({ariaLabel, onChange, options, threeColumns = false, value}) => <div role="group" aria-label={ariaLabel} className="grid gap-1 rounded-lg bg-gray-100 p-1 dark:bg-white/10" style={{
    gridTemplateColumns: `repeat(${threeColumns ? 3 : options.length}, minmax(0, 1fr))`
  }}>
      {options.map(option => <button key={option.value} type="button" aria-pressed={value === option.value} onClick={() => onChange(option.value)} className={classNames("min-h-8 rounded-md px-2 py-1.5 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40", value === option.value ? "bg-white text-gray-950 shadow-sm dark:bg-white/15 dark:text-white" : "text-gray-600 hover:text-gray-950 dark:text-gray-400 dark:hover:text-white")}>
          {option.label}
        </button>)}
    </div>;
  const renderSelectField = ({label, onChange, options, value}) => <label className="flex min-w-0 flex-col text-sm font-medium text-gray-700 dark:text-gray-300">
      <span className="mb-2">{label}</span>
      <select value={value} onChange={event => onChange(event.target.value)} className="h-10 w-full rounded-xl border border-gray-950/10 bg-transparent px-3 text-sm font-normal text-gray-950 outline-none transition-shadow focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-white/10 dark:text-white">
        {options.map(option => <option key={option.value} value={option.value}>
            {option.label}
          </option>)}
      </select>
    </label>;
  const renderToggleRow = ({checked, description, label, onChange}) => <label className="flex cursor-pointer items-center justify-between gap-5 py-3">
      <span className="min-w-0">
        <span className="block text-sm font-medium text-gray-950 dark:text-white">
          {label}
        </span>
        <span className="block text-sm text-gray-600 dark:text-gray-400">
          {description}
        </span>
      </span>
      <span className="relative inline-flex shrink-0 rounded-full focus-within:ring-2 focus-within:ring-primary/40">
        <input type="checkbox" role="switch" checked={checked} onChange={event => onChange(event.target.checked)} className="sr-only" />
        <span aria-hidden="true" className={classNames("h-5 w-9 rounded-full transition-colors", checked ? "bg-primary" : "bg-gray-200 dark:bg-white/15")} />
        <span aria-hidden="true" className={classNames("pointer-events-none absolute left-0.5 top-0.5 size-4 rounded-full bg-white shadow-sm transition-all", checked && "ml-4")} />
      </span>
    </label>;
  const appearance = useMemo(() => ({
    variant,
    theme,
    accent,
    radius: `${radius}px`,
    side,
    align
  }), [accent, align, radius, side, theme, variant]);
  const updatePreview = useCallback(() => {
    const previewWindow = previewRef.current?.contentWindow;
    if (!previewWindow) return;
    const liveTheme = appearance.theme === "system" ? document.documentElement.classList.contains("dark") ? "dark" : "light" : appearance.theme;
    previewWindow.postMessage({
      type: PREVIEW_UPDATE_MESSAGE,
      trackEvents,
      reportErrors,
      appearance: {
        ...appearance,
        theme: liveTheme
      }
    }, window.location.origin);
  }, [appearance, reportErrors, trackEvents]);
  useEffect(() => {
    const handlePreviewMessage = event => {
      if (event.source !== previewRef.current?.contentWindow) return;
      if (event.data?.type === PREVIEW_READY_MESSAGE) {
        updatePreview();
        return;
      }
      if (event.data?.type === PREVIEW_STATE_MESSAGE) {
        setPreviewStatus(event.data.state === "error" ? "error" : "ready");
      }
    };
    const themeObserver = new MutationObserver(updatePreview);
    window.addEventListener("message", handlePreviewMessage);
    themeObserver.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    updatePreview();
    return () => {
      window.removeEventListener("message", handlePreviewMessage);
      themeObserver.disconnect();
    };
  }, [updatePreview]);
  useEffect(() => {
    if (!previewHostReady || !previewUrl || previewStatus !== "loading") {
      return undefined;
    }
    const timeout = window.setTimeout(() => {
      setPreviewStatus(status => status === "loading" ? "error" : status);
    }, 20000);
    return () => window.clearTimeout(timeout);
  }, [previewHostReady, previewStatus, previewUrl]);
  const configLines = ["{", `  id: '${EXAMPLE_WIDGET_ID}',`, `  supportEmail: '${SUPPORT_EMAIL}',`, "  starterQuestions: [", ...STARTER_QUESTIONS.map(question => `    '${question}',`), "  ],", "  appearance: {", `    variant: '${variant}',`, `    theme: '${theme}',`, `    accent: '${accent}',`, `    radius: '${radius}px',`, `    side: '${side}',`, `    align: '${align}',`, "  },"];
  if (trackEvents || reportErrors) {
    configLines.push("  hooks: {");
    if (trackEvents) {
      configLines.push("    event(event) {", "      console.log('Assistant event', event);", "    },");
    }
    if (reportErrors) {
      configLines.push("    error(error) {", "      console.error('Assistant error', error.code, error);", "    },");
    }
    configLines.push("  },");
  }
  configLines.push("}");
  const configCode = configLines.join("\n");
  const indentedConfig = configCode.split("\n").join("\n  ");
  const htmlCode = `<script
  type="module"
  src="${EMBED_URL}"
></script>
<script type="module">
  await window.MintlifyAssistant.init(${indentedConfig});
</script>`;
  const nextCode = `'use client';

import Script from 'next/script';

const ASSISTANT_CONFIG = ${configCode};

export const AssistantWidget = () => (
  <Script
    type="module"
    src="${EMBED_URL}"
    onReady={() => {
      void window.MintlifyAssistant.init(ASSISTANT_CONFIG);
    }}
  />
);`;
  const installCode = installTarget === "html" ? htmlCode : nextCode;
  return <div className="my-6 grid gap-8" data-assistant-playground-layout="">
      <div className="min-w-0">
        <div className="not-prose overflow-hidden rounded-xl border border-gray-950/10 dark:border-white/10">
          <div className="px-5 py-4">
            <div className="text-sm font-medium text-gray-950 dark:text-white">
              Widget playground
            </div>
            <p className="mt-0.5 text-sm text-gray-600 dark:text-gray-400">
              Changes apply to the widget preview.
            </p>
          </div>

          <div className="border-t border-gray-950/10 px-5 py-5 dark:border-white/10">
            <div className="space-y-6">
              <fieldset>
                <legend className="mb-2 text-sm font-medium text-gray-950 dark:text-white">
                  Variants
                </legend>
                {renderSegmentedControl({
    ariaLabel: "Variants",
    value: variant,
    options: VARIANT_OPTIONS,
    onChange: setVariant
  })}
              </fieldset>

              <div className="grid gap-4 sm:grid-cols-2">
                {renderSelectField({
    label: "Theme",
    value: theme,
    options: THEME_OPTIONS,
    onChange: setTheme
  })}

                <label className="flex min-w-0 flex-col text-sm font-medium text-gray-700 dark:text-gray-300">
                  <span className="mb-2">Accent</span>
                  <span className="flex h-10 items-center gap-2 rounded-xl border border-gray-950/10 px-2 dark:border-white/10">
                    <input type="color" value={accent} onChange={event => setAccent(event.target.value)} aria-label="Accent color" className="h-7 w-8 cursor-pointer rounded border-0 bg-transparent p-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40" />
                    <span className="font-mono text-xs font-normal text-gray-600 dark:text-gray-400">
                      {accent}
                    </span>
                  </span>
                </label>
              </div>

              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
                <span className="mb-2 flex items-center justify-between">
                  Corner radius
                  <output className="font-mono text-xs font-normal text-gray-500 dark:text-gray-400">
                    {radius}px
                  </output>
                </span>
                <input type="range" min="0" max="32" step="2" value={radius} onChange={event => setRadius(Number.parseInt(event.target.value))} className="block w-full accent-primary" />
              </label>

              <div className="grid gap-4 sm:grid-cols-2">
                <fieldset>
                  <legend className="mb-2 text-sm font-medium text-gray-950 dark:text-white">
                    Trigger side
                  </legend>
                  {renderSegmentedControl({
    ariaLabel: "Trigger side",
    threeColumns: true,
    value: side,
    options: SIDE_OPTIONS,
    onChange: setSide
  })}
                </fieldset>

                <fieldset>
                  <legend className="mb-2 text-sm font-medium text-gray-950 dark:text-white">
                    Trigger alignment
                  </legend>
                  {renderSegmentedControl({
    ariaLabel: "Trigger alignment",
    value: align,
    options: ALIGN_OPTIONS,
    onChange: setAlign
  })}
                </fieldset>
              </div>

              <fieldset>
                <legend className="text-sm font-medium text-gray-950 dark:text-white">
                  Hooks
                </legend>
                <div className="mt-1 divide-y divide-gray-950/10 dark:divide-white/10">
                  {renderToggleRow({
    label: "Lifecycle events",
    description: "Observe open, close, ask, update, and navigation events.",
    checked: trackEvents,
    onChange: setTrackEvents
  })}
                  {renderToggleRow({
    label: "Structured errors",
    description: "Receive stable error codes and retry metadata.",
    checked: reportErrors,
    onChange: setReportErrors
  })}
                </div>
              </fieldset>
            </div>
          </div>

          <div className="border-t border-gray-950/10 p-5 dark:border-white/10">
            <div className="mb-3 flex flex-wrap items-center justify-between gap-3">
              <div>
                <div className="text-sm font-medium text-gray-950 dark:text-white">
                  Install
                </div>
                <div className="mt-0.5 text-sm text-gray-600 dark:text-gray-400">
                  Copy the generated setup for your stack.
                </div>
              </div>
              {renderSegmentedControl({
    ariaLabel: "Installation target",
    value: installTarget,
    options: INSTALL_OPTIONS,
    onChange: setInstallTarget
  })}
            </div>

            <CodeBlockComponent language="jsx" filename={installTarget === "html" ? "index.html" : "assistant-widget.jsx"} wrap>
              {installCode}
            </CodeBlockComponent>
          </div>
        </div>
        {children ? <div className="mt-8">{children}</div> : null}
      </div>

      <aside className="not-prose" data-assistant-preview="">
        <div ref={previewHostRef} className="relative flex h-[42rem] min-h-0 flex-col overflow-hidden rounded-xl border border-gray-950/10 bg-transparent dark:border-white/10 lg:sticky lg:top-20 lg:h-[calc(100vh-6rem)]" data-assistant-preview-card="">
          {previewHostReady && previewUrl ? <iframe ref={previewRef} title="Live Assistant Widget preview" src={previewUrl} onLoad={updatePreview} scrolling="no" className="min-h-0 w-full flex-1 border-0 bg-transparent [color-scheme:light_dark] dark:[color-scheme:dark]" /> : null}
          {previewStatus !== "ready" ? <div aria-live="polite" role="status" className="pointer-events-none absolute inset-0 z-10 flex items-center justify-center gap-3 px-6 text-center text-sm text-gray-600 dark:text-gray-400">
              {previewStatus === "loading" ? <span aria-hidden="true" className="size-[18px] shrink-0 animate-spin rounded-full border-[1.5px] border-gray-300 border-t-gray-600 motion-reduce:animate-none dark:border-gray-600 dark:border-t-gray-300" /> : null}
              <span>
                {previewStatus === "loading" ? "Loading assistant preview..." : "The live preview could not load. It requires a deployed docs site and the browser console may have details."}
              </span>
            </div> : null}
        </div>
      </aside>
    </div>;
};

export const WidgetCodeBlock = ({children, ...props}) => <CodeBlock {...props}>{children}</CodeBlock>;

L'[assistant](/docs/fr/assistant) répond aux questions sur votre site Mintlify. Pour intégrer la même capacité sur un autre site ou application web, utilisez le widget. Grâce au widget, vous pouvez donner à vos utilisateurs l'accès à un chat IA entraîné sur votre contenu dans le tableau de bord de votre produit, votre site marketing, votre portail d'assistance ou ailleurs.

Ajoutez le widget à n'importe quel site web ou application web à l'aide d'un script hébergé. Le widget possède son propre déclencheur et s'affiche dans un Shadow DOM fermé, ce qui empêche les styles de votre application d'affecter le widget.

La seule option de navigateur requise est l'ID public du widget. Gérez l'état d'activation, les origines autorisées, les pièces jointes et la protection contre les bots dans votre tableau de bord. Définissez les questions d'introduction spécifiques à l'intégration et une adresse e-mail d'assistance dans la configuration du navigateur.

<div id="prerequisites">
  ## Prérequis
</div>

* Un [plan Pro ou Enterprise](https://mintlify.com/pricing?ref=assistant). Le widget utilise les mêmes crédits que l'assistant.

<div id="enable-the-widget">
  ## Activer le widget
</div>

1. Accédez à la page [Widget](https://app.mintlify.com/settings/deployment/widget) de votre déploiement.
2. Activez le widget.
3. Ajoutez les origines autorisées où vous intégrez le widget.
4. Copiez l'ID du widget.

<div id="install-and-configure">
  ## Installer et configurer
</div>

Utilisez le playground pour configurer la présentation, les options visuelles et les hooks d'observation de votre widget. Le bloc de code d'installation se met à jour à mesure que vous modifiez chaque option.

<Info>
  Remplacez `YOUR_WIDGET_ID` dans le code généré par l'ID du widget de la page [Widget](https://app.mintlify.com/settings/deployment/widget) de votre tableau de bord.
</Info>

Après avoir ajouté le code généré à votre site, rechargez la page. Vérifiez que le déclencheur apparaît, puis cliquez dessus et envoyez une question de test pour confirmer que le widget est connecté.

<AssistantWidgetPlayground CodeBlockComponent={WidgetCodeBlock}>
  <Warning>
    Les scripts de module sont différés et exécutés dans l'ordre du document. Gardez le chargeur hébergé avant le bloc d'initialisation lorsque vous installez le widget en HTML, sinon le widget ne parvient pas à se monter.
  </Warning>

  <div id="open-on-initialization">
    ## Ouvrir lors de l'initialisation
  </div>

  Définissez `defaultOpen` sur `true` pour ouvrir le widget immédiatement après son premier montage :

  ```js theme={null}
  await window.MintlifyAssistant.init({
    id: "YOUR_WIDGET_ID",
    defaultOpen: true,
  });
  ```

  `defaultOpen` est par défaut à `false` et ne s'applique qu'à la première initialisation. Appeler à nouveau `init()` avec le même ID de widget et le même endpoint API ne rouvre pas un widget qu'un visiteur a fermé. Utilisez `open()` et `close()` pour le contrôler après l'initialisation.

  <div id="use-a-custom-trigger">
    ## Utiliser un déclencheur personnalisé
  </div>

  Attendez `init()` avant d'appeler d'autres méthodes. Conservez le déclencheur intégré ou ouvrez la présentation configurée depuis n'importe quel bouton de votre application.

  ```js theme={null}
  await window.MintlifyAssistant.init({
    id: "YOUR_WIDGET_ID",
    supportEmail: "hi@mintlify.com",
    starterQuestions: [
      "How do I get started with Mintlify?",
      "How do I customize my docs?",
      "How do I deploy my docs?",
    ],
  });

  document.querySelector("#help-button").addEventListener("click", () => {
    void window.MintlifyAssistant.open({
      source: "help-button",
      focus: true,
    });
  });
  ```

  Pour ouvrir le widget et envoyer immédiatement une question, appelez `ask()` :

  ```js theme={null}
  await window.MintlifyAssistant.ask("How do I authenticate?", {
    source: "authentication-guide",
    open: true,
    focus: true,
  });
  ```

  Les métadonnées d'événement et les requêtes incluent la valeur `source`, ce qui vous permet de distinguer les interactions intégrées de vos points d'entrée personnalisés.

  <div id="update-a-mounted-widget">
    ## Mettre à jour un widget monté
  </div>

  Utilisez `update()` pour modifier l'apparence, les libellés, l'e-mail d'assistance, les questions d'introduction ou les hooks sans effacer la conversation en cours. Seuls les champs fournis sont modifiés.

  ```js theme={null}
  await window.MintlifyAssistant.update({
    appearance: {
      theme: "dark",
      accent: "#7c3aed",
    },
    labels: {
      title: "Docs copilot",
      trigger: "Ask docs",
    },
    supportEmail: "support@example.com",
    starterQuestions: [
      "How do I get started?",
      "How do I manage my account?",
    ],
  });
  ```

  Passez `null` pour restaurer un champ ou un groupe à sa valeur par défaut, supprimer l'e-mail d'assistance ou restaurer une liste vide de questions d'introduction :

  ```js theme={null}
  await window.MintlifyAssistant.update({
    appearance: {
      accent: null,
    },
    supportEmail: null,
    starterQuestions: null,
    hooks: null,
  });
  ```

  La modification de `identity` démarre une nouvelle conversation. La modification de l'ID du widget ou de l'endpoint API nécessite d'appeler `destroy()` avant un nouveau `init()`.

  Vous pouvez fournir `supportEmail` et `starterQuestions` lors de l'initialisation et les modifier ultérieurement avec `update()`. Ces valeurs s'appliquent à l'intégration en cours et ne sont pas héritées de votre tableau de bord Mintlify.

  <div id="configuration-reference">
    ## Référence de configuration
  </div>

  <div id="assistantconfig">
    ### `AssistantConfig`
  </div>

  Passez cet objet à `init()`.

  | Option             | Type                                          | Description                                                                                      |
  | ------------------ | --------------------------------------------- | ------------------------------------------------------------------------------------------------ |
  | `id`               | string                                        | ID public du widget provenant du tableau de bord Mintlify.                                       |
  | `endpoint`         | string                                        | Remplace l'endpoint API du widget hébergé.                                                       |
  | `identity`         | string                                        | Jeton d'identité signé de l'utilisateur final. Omettez-le pour les visiteurs anonymes.           |
  | `nonce`            | string                                        | Nonce CSP copié dans les ressources créées par le widget.                                        |
  | `defaultOpen`      | boolean                                       | Ouvre le widget lors de sa première initialisation. La valeur par défaut est `false`.            |
  | `appearance`       | [`AssistantAppearance`](#assistantappearance) | Substitutions visuelles et de présentation.                                                      |
  | `labels`           | [`AssistantLabels`](#assistantlabels)         | Substitutions du texte visible par le client.                                                    |
  | `supportEmail`     | string                                        | Définit l'adresse d'assistance affichée dans la barre d'outils du widget pour cette intégration. |
  | `starterQuestions` | string\[]                                     | Définit jusqu'à **trois** invites d'état vide pour cette intégration.                            |
  | `hooks`            | [`AssistantHooks`](#assistanthooks)           | Observateurs d'événements et d'erreurs.                                                          |

  <div id="assistantappearance">
    ### `AssistantAppearance`
  </div>

  | Option                     | Values                                                         | Description                                                                                                          |
  | -------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
  | `variant`                  | `widget`, `modal`, `panel`                                     | Contrôle si l'assistant s'ouvre comme un popover ancré, une boîte de dialogue centrée ou un panneau latéral réactif. |
  | `theme`                    | `light`, `dark`, `system`                                      | Définit le schéma de couleurs du widget. La valeur par défaut est `system`.                                          |
  | `accent`                   | CSS color                                                      | Définit la couleur des contrôles principaux.                                                                         |
  | `radius`                   | CSS border radius                                              | Définit le rayon du panneau, par exemple `18px`.                                                                     |
  | `font`                     | CSS font family                                                | Utilise une police déjà chargée par votre application. Par défaut, Inter est intégrée.                               |
  | `side`                     | `top`, `bottom`, `left`, `right`, `inline-start`, `inline-end` | Positionne le déclencheur intégré sur un bord de l'écran.                                                            |
  | `align`                    | `start`, `center`, `end`                                       | Aligne le déclencheur le long du bord sélectionné.                                                                   |
  | `dismissOnInteractOutside` | boolean                                                        | Contrôle si les interactions du pointeur ou du focus à l'extérieur ferment l'assistant.                              |
  | `logo`                     | URL or `{ light, dark }`                                       | Remplace la marque Mintlify par défaut.                                                                              |
  | `zIndex`                   | number                                                         | Modifie l'ordre d'empilement de l'hôte du widget.                                                                    |

  Les substitutions CSS arbitraires et les palettes neutres ne sont pas prises en charge. Le Shadow DOM fermé protège à la fois votre application et le widget des régressions de style entre sites.

  <div id="assistantlabels">
    ### `AssistantLabels`
  </div>

  | Option        | Values                     | Description                                                                                      |
  | ------------- | -------------------------- | ------------------------------------------------------------------------------------------------ |
  | `title`       | string or `null`           | Définit l'en-tête du panneau. La valeur par défaut est `Assistant`.                              |
  | `trigger`     | string or `null`           | Définit le texte compact du widget et du déclencheur du panneau.                                 |
  | `placeholder` | string or `null`           | Définit le placeholder du compositeur et du déclencheur modal.                                   |
  | `disclaimer`  | string, `false`, or `null` | Définit l'avis d'état vide. Passez `false` pour le masquer.                                      |
  | `suggestions` | string or `null`           | Définit le titre au-dessus des questions d'introduction. La valeur par défaut est `Suggestions`. |

  <div id="assistanthooks">
    ### `AssistantHooks`
  </div>

  ```js theme={null}
  hooks: {
    event(event) {
      console.log(event.type, event.actor, event.source);
    },
    error(error) {
      console.error(error.code, error.retryable, error.status);
    },
  }
  ```

  Le hook `event` reçoit les métadonnées de cycle de vie et d'interaction pour `init`, `open`, `close`, `ask`, `update`, `reset`, `navigate` et `destroy`. Les événements n'incluent pas le texte de la question, l'identité, la session ou les jetons CAPTCHA.

  Le hook `error` reçoit un `code` stable, un booléen `retryable` et un `status` HTTP facultatif. Les exceptions levées par l'un ou l'autre des hooks n'interrompent pas le widget.

  <div id="assistantopenoptions">
    ### `AssistantOpenOptions`
  </div>

  Passez cet objet facultatif à `open()`.

  | Option   | Type    | Description                                                                       |
  | -------- | ------- | --------------------------------------------------------------------------------- |
  | `source` | string  | Attribution définie par le client incluse dans les événements et les requêtes.    |
  | `focus`  | boolean | Met le focus sur le compositeur après ouverture. La valeur par défaut est `true`. |

  <div id="assistantaskoptions">
    ### `AssistantAskOptions`
  </div>

  Passez cet objet facultatif après la chaîne de question dans `ask()`.

  | Option   | Type    | Description                                                                           |
  | -------- | ------- | ------------------------------------------------------------------------------------- |
  | `source` | string  | Attribution définie par le client incluse dans les événements et les requêtes.        |
  | `open`   | boolean | Ouvre le panneau avant d'envoyer. La valeur par défaut est `true`.                    |
  | `focus`  | boolean | Met le focus sur le compositeur lors de l'ouverture. La valeur par défaut est `true`. |

  <div id="assistantupdate">
    ### `AssistantUpdate`
  </div>

  Passez cet objet à `update()`. Chaque champ est facultatif, et `null` restaure sa valeur par défaut.

  | Option             | Type                                                    | Description                                                                |
  | ------------------ | ------------------------------------------------------- | -------------------------------------------------------------------------- |
  | `identity`         | string or `null`                                        | Change l'identité signée et démarre une nouvelle conversation.             |
  | `appearance`       | [`AssistantAppearance`](#assistantappearance) or `null` | Applique un patch profond aux paramètres d'apparence.                      |
  | `labels`           | [`AssistantLabels`](#assistantlabels) or `null`         | Applique un patch profond au texte visible par le client.                  |
  | `supportEmail`     | string or `null`                                        | Change l'adresse d'assistance. Passez `null` pour la supprimer.            |
  | `starterQuestions` | string\[] or `null`                                     | Change jusqu'à trois invites. Passez `null` pour restaurer une liste vide. |
  | `hooks`            | [`AssistantHooks`](#assistanthooks) or `null`           | Applique un patch profond aux observateurs d'événements et d'erreurs.      |

  <div id="browser-api">
    ## API du navigateur
  </div>

  | Method                   | Parameter types                                       | Description                                                                                               |
  | ------------------------ | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
  | `init(config)`           | [`AssistantConfig`](#assistantconfig)                 | Charge et monte le widget. Il s'agit de la promesse de disponibilité pour toutes les autres méthodes.     |
  | `open(options)`          | [`AssistantOpenOptions`](#assistantopenoptions)       | Ouvre la présentation configurée.                                                                         |
  | `close()`                | —                                                     | Ferme le widget.                                                                                          |
  | `ask(question, options)` | string, [`AssistantAskOptions`](#assistantaskoptions) | Ouvre le widget si demandé et envoie une question.                                                        |
  | `update(config)`         | [`AssistantUpdate`](#assistantupdate)                 | Applique un patch profond aux paramètres modifiables d'identité, d'apparence, de texte et d'observateurs. |
  | `reset()`                | —                                                     | Démarre une nouvelle conversation.                                                                        |
  | `destroy()`              | —                                                     | Supprime le widget et libère ses ressources navigateur.                                                   |

  Les instantanés de conversation restent privés au widget. Chaque méthode se résout en `void`.

  <div id="content-security-policy">
    ## Content Security Policy
  </div>

  Si votre site utilise une Content Security Policy, autorisez les origines requises par les fonctionnalités de votre widget activées :

  | Directive                                    | Source                              | Required for                      |
  | -------------------------------------------- | ----------------------------------- | --------------------------------- |
  | `script-src`                                 | `https://cdn.jsdelivr.net`          | Chargeur et runtime du widget     |
  | `connect-src`                                | `https://api.mintlify.com`          | API du widget                     |
  | `style-src`                                  | `https://cdn.jsdelivr.net`          | Feuille de style du widget        |
  | `font-src`                                   | `https://cdn.jsdelivr.net`          | Police Inter intégrée facultative |
  | `script-src`, `connect-src`, and `frame-src` | `https://challenges.cloudflare.com` | Protection anti-bot Turnstile     |
  | `script-src`                                 | `https://js.hcaptcha.com`           | Protection anti-bot hCaptcha      |
  | `connect-src` and `frame-src`                | `https://*.hcaptcha.com`            | Protection anti-bot hCaptcha      |

  Une politique `script-src` stricte doit toujours autoriser à la fois le chargeur et le script d'initialisation. Passer `nonce` à `init()` ne le propage qu'aux ressources créées par le widget après l'initialisation.
</AssistantWidgetPlayground>


## Related topics

- [Intercom](/docs/fr/integrations/support/intercom.md)
- [Front](/docs/fr/integrations/support/front.md)
- [Intégrations](/docs/fr/organize/settings-integrations.md)
