Un widget réutilisable qui intègre l’assistant directement dans votre application. Le widget propose :
- Un bouton flottant qui ouvre un panneau de conversation lorsqu’on clique dessus
- Des réponses diffusées en temps réel, basées sur les informations de votre documentation
- Un rendu des messages avec prise en charge de Markdown
Les utilisateurs peuvent utiliser le widget pour obtenir de l’aide sur votre produit sans quitter votre application.
- Offre Mintlify Pro ou Custom
- Votre nom de domaine, qui apparaît à la fin de l’URL de votre Dashboard. Par exemple, si l’URL de votre Dashboard est
https://dashboard.mintlify.com/org-name/domain-name, votre nom de domaine est domain-name
- Une API key de l’Assistant
- Node.js v18 ou version ultérieure et npm installés
- Connaissances de base de React
Récupérer votre clé d’API Assistant
- Accédez à la page API keys de votre Dashboard.
- Cliquez sur Create Assistant API Key.
- Copiez la clé d’API Assistant (commence par
mint_dsc_) et conservez-la en lieu sûr.
La clé d’API Assistant est un jeton public pouvant être utilisé dans le code frontend. Les appels effectués avec ce jeton sont décomptés de l’allocation de messages de votre offre et peuvent entraîner des dépassements.
La manière la plus rapide de commencer consiste à cloner le référentiel d’exemple et à le personnaliser selon vos besoins.
Cloner le référentiel
git clone https://github.com/mintlify/assistant-embed-example.git
cd assistant-embed-example
npm install
Configurer votre projet
Ouvrez src/config.js et mettez-le à jour avec les détails de votre projet Mintlify :export const ASSISTANT_CONFIG = {
domain: 'your-domain',
docsURL: 'https://yourdocs.mintlify.app',
};
Remplacez :
your-domain par le domain de votre projet Mintlify, visible à la fin de l’URL de votre Dashboard.
https://yourdocs.mintlify.app par l’URL réelle de votre documentation.
Ajouter votre jeton d’API
Créez un fichier .env à la racine du projet :VITE_MINTLIFY_TOKEN=mint_dsc_your_token_here
Remplacez mint_dsc_your_token_here par votre API key de l’Assistant. Démarrer le serveur de développement
Ouvrez votre application dans un navigateur et cliquez sur le bouton Ask pour ouvrir le widget de l’Assistant.
L’exemple utilise une architecture orientée composants.
src/
├── App.css # Styles de l'application
├── App.jsx # Composant principal de l'application qui affiche le widget
├── config.js # Configuration (domain et docsURL)
├── index.css # Styles globaux
├── main.jsx # Point d'entrée
├── utils.js # Fonctions utilitaires pour analyser les suggestions et extraire les sources
└── components/
├── AssistantWidget.jsx # Composant widget principal avec l'état du chat et la logique API
└── Message.jsx # Composant de message individuel pour afficher les messages de l'utilisateur et de l'Assistant
Fichiers clés :
src/App.jsx: Composant principal de l’application. Montre comment importer et utiliser le composant AssistantWidget.
src/config.js: Configuration centralisée. Mettez à jour ce fichier avec votre domain et l’URL de la documentation.
src/components/AssistantWidget.jsx: Composant principal du widget. Gère l’état d’ouverture/fermeture, les messages de chat et les appels à l’API.
src/utils.js: Contient des fonctions utilitaires pour analyser le format de réponse de l’Assistant et extraire les sources.
src/components/Message.jsx: Affiche chaque message individuellement avec prise en charge de Markdown et des liens de suggestion.
Idées de personnalisation
Extraire et afficher les sources à partir des réponses de l’Assistant :
const extractSources = (parts) => {
return parts
?.filter(p => p.type === 'tool-invocation' && p.toolInvocation?.toolName === 'search')
.flatMap(p => p.toolInvocation?.result || [])
.map(source => ({
url: source.url || source.path,
title: source.metadata?.title || source.path,
})) || [];
};
// In your message rendering:
{messages.map((message) => {
const sources = message.role === 'assistant' ? extractSources(message.parts) : [];
return (
<div key={message.id}>
{/* contenu du message */}
{sources.length > 0 && (
<div className="mt-2 text-xs">
<p className="font-semibold">Sources :</p>
{sources.map((s, i) => (
<a key={i} href={s.url} target="_blank" rel="noopener noreferrer" className="text-blue-600">
{s.title}
</a>
))}
</div>
)}
</div>
);
})}
Suivre les identifiants des fils de conversation
Stockez les identifiants de fil pour conserver l’historique des conversations entre les sessions :
import { useState, useEffect } from 'react';
export function AssistantWidget({ domain, docsURL }) {
const [threadId, setThreadId] = useState(null);
useEffect(() => {
// Récupérer l'ID de conversation enregistré depuis localStorage
const saved = localStorage.getItem('assistant-thread-id');
if (saved) {
setThreadId(saved);
}
}, []);
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
api: `https://api-dsc.mintlify.com/v1/assistant/${domain}/message`,
headers: {
'Authorization': `Bearer ${import.meta.env.VITE_MINTLIFY_TOKEN}`,
},
body: {
fp: 'anonymous',
retrievalPageSize: 5,
...(threadId && { threadId }), // Inclure l'ID de conversation si disponible
},
streamProtocol: 'data',
sendExtraMessageFields: true,
fetch: async (url, options) => {
const response = await fetch(url, options);
const newThreadId = response.headers.get('x-thread-id');
if (newThreadId) {
setThreadId(newThreadId);
localStorage.setItem('assistant-thread-id', newThreadId);
}
return response;
},
});
// ... reste du composant
}
Ajouter des raccourcis clavier
Permettez aux utilisateurs d’ouvrir le widget et d’envoyer des messages à l’aide de raccourcis clavier :
useEffect(() => {
const handleKeyDown = (e) => {
// Cmd/Ctrl + Shift + I pour afficher/masquer le widget
if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === 'I') {
e.preventDefault();
setIsOpen((prev) => !prev);
}
// Entrée (lorsque le widget a le focus) pour envoyer
if (e.key === 'Enter' && !e.shiftKey && document.activeElement.id === 'assistant-input') {
e.preventDefault();
handleSubmit();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [handleSubmit]);