Référence SDK
@askdialog/dialog-sdk est le SDK core pour embedder Dialog dans des stacks custom. Il gère la communication avec l’API Dialog, le cycle de vie de l’assistant, le tracking, et expose tout ce dont vous avez besoin pour construire une UI autour.
Depuis npm :
npm install @askdialog/dialog-sdk# oupnpm add @askdialog/dialog-sdk# ouyarn add @askdialog/dialog-sdkDepuis CDN (sans bundler) :
<script src="https://d2m6yt8rnm4dos.cloudfront.net/dialog-sdk.X.Y.Z.min.js"></script>Chargé via CDN, le SDK est exposé en window.DialogSDK.
Instancier
Section intitulée « Instancier »import { Dialog, type SimplifiedProduct } from '@askdialog/dialog-sdk'
const client = new Dialog({ apiKey: 'YOUR_PUBLIC_API_KEY', locale: 'fr', currency: 'EUR', callbacks: { addToCart: async ({ productId, quantity, variantId, currency }) => { // Ajoutez le produit au panier et refresh votre UI }, changeCartQuantity: async ({ productId, variantId, quantity }) => { // Optionnel : passez cette ligne du panier à `quantity` et mettez à jour votre UI }, getProduct: async (productId, variantId): Promise<SimplifiedProduct> => { // Récupérez le produit depuis votre backend et renvoyez-le au format SimplifiedProduct }, },})Options du constructor
Section intitulée « Options du constructor »| Option | Type | Requis | Description |
|---|---|---|---|
apiKey |
string |
Oui | Votre clé API publique Dialog. |
locale |
string |
Oui | Locale active (ex. 'en', 'fr', 'es'). |
callbacks.addToCart |
(params) => Promise<void> |
Oui | Appelée quand l’utilisateur clique sur add-to-cart dans l’assistant. Vous gérez la mutation panier et le refresh UI. |
callbacks.getProduct |
(productId, variantId?) => Promise<SimplifiedProduct> |
Oui | Appelée pour afficher les cards produit dans l’assistant. Renvoyez votre produit au format SimplifiedProduct. |
callbacks.changeCartQuantity |
(params) => Promise<void> |
Non | Appelée quand le visiteur ajuste la quantité d’une ligne que l’assistant vient d’ajouter. quantity est la nouvelle quantité absolue de la ligne. Sans ce callback, l’assistant masque son stepper de quantité. |
currency |
string |
Oui | Devise de la boutique, ISO 4217 (ex. 'USD', 'EUR'), indépendante de la locale. Relue via client.currency ; Search s’en sert pour choisir l’index. |
callbacks.addToCart |
(params) => Promise<void> |
Non | Appelée quand l’utilisateur clique sur add-to-cart dans l’assistant. Vous gérez la mutation panier et le refresh UI. |
callbacks.getProduct |
(productId, variantId?) => Promise<SimplifiedProduct> |
Non | Appelée pour afficher les cards produit dans l’assistant. Renvoyez votre produit au format SimplifiedProduct. |
theme |
Theme |
Non | Override du thème visuel (couleurs, polices, forme des CTA). |
userId |
string |
Non | ID stable de visiteur. Si omis, Dialog en génère un automatiquement et le persiste. |
product |
{ id: string; variantId?: string } |
Non | Le produit de la page courante. Ancre les questions sans produit propre (bookmark flottant, reprise, champ libre) sur le produit consulté. Voir Déclarer le produit courant. |
disableAddToCart |
boolean |
Non | Masque l’add-to-cart Dialog pour cette instance/session du widget (défaut false). Voir « Désactiver l’add-to-cart » ci-dessous. |
analyticsConsent |
'granted' |
Non | Déclare le consentement analytics comme accordé, pour les sites sans bannière de cookies. Omis par défaut. Voir Déclarer le consentement analytics. |
callbacks peut être omis dans une intégration Search seule (voir Search) : seul l’assistant en a besoin, et les méthodes getProduct() et addToCart() du client lèvent une erreur de configuration quand leur callback manque.
Désactiver l’add-to-cart
Section intitulée « Désactiver l’add-to-cart »Mets disableAddToCart: true pour désactiver l’add-to-cart Dialog sur une session précise : par exemple une boutique B2B qui masque les actions d’achat quand un client B2B est connecté. Évalue ta propre condition à l’initialisation :
const client = new Dialog({ apiKey: 'YOUR_PUBLIC_API_KEY', locale: 'fr', currency: 'EUR', disableAddToCart: isB2BCustomerLoggedIn, // par session callbacks: { /* ... */ },})Quand c’est activé :
- l’assistant masque le CTA add-to-cart sur les cards de recommandation et les cards produit conversationnelles ;
callbacks.addToCartn’est jamais appelé et aucun événement add-to-cart n’est tracké ;- les liens produit et la navigation des recommandations restent disponibles.
Omets-le (ou mets false) pour garder le comportement actuel. Le flag est lu à l’initialisation : il s’applique pour toute la durée de vie de l’instance du widget (un changement d’état de connexion prend effet au rechargement suivant).
Déclarer le consentement analytics
Section intitulée « Déclarer le consentement analytics »Par défaut, l’assistant n’envoie les événements analytics (add-to-cart, checkout, usage de l’assistant) qu’après avoir détecté un signal de consentement sur la page : Google Consent Mode, TCF v2 ou OneTrust. Un site sans bannière de cookies n’émet aucun signal : aucun événement n’est envoyé pour ses visiteurs et le dashboard reste vide.
Sur ces sites, le paramètre analyticsConsent: 'granted' déclare le consentement comme accordé :
const client = new Dialog({ apiKey: 'YOUR_PUBLIC_API_KEY', locale: 'fr', currency: 'EUR', analyticsConsent: 'granted', // pas de bannière de cookies sur ce site callbacks: { /* ... */ },})Le paramètre se comporte comme un état default de Google Consent Mode :
- l’analytics est actif dès la première page vue, pour tous les visiteurs ;
- un refus émis par une plateforme de consentement présente sur la page reste prioritaire : un
updateGoogle Consent Mode àdenied, ou OneTrust chargé sans le groupe performance (C0002), désactive l’analytics pour ce visiteur ; window.dialog.audit.consentindiquedetectedCmp: 'declared'quand c’est le paramètre qui a activé l’analytics.
Considérer le consentement comme acquis relève de la décision de conformité du marchand. Sans ce paramètre, la détection par défaut s’applique.
Déclarer le produit courant
Section intitulée « Déclarer le produit courant »Sur les pages produit, le paramètre product indique à l’assistant quel produit le visiteur regarde. Les questions posées sans produit explicite (depuis le bookmark flottant, la reprise de conversation ou le champ libre) sont alors répondues dans le contexte de ce produit, y compris après une navigation d’une page produit à une autre :
const client = new Dialog({ apiKey: 'YOUR_PUBLIC_API_KEY', locale: 'fr', currency: 'EUR', product: { id: 'product-123', variantId: 'variant-456' }, // variantId optionnel callbacks: { /* ... */ },})Sur une boutique single-page, mettre la déclaration à jour à chaque navigation côté client :
client.setCurrentProduct('product-456', 'variant-789') // variantId optionnelclient.clearCurrentProduct() // sortie vers une page non-produitL’id doit correspondre à l’ID produit du flux catalogue Dialog. Sans produit déclaré, les questions posées hors d’un clic produit sont répondues sans contexte produit.
Charger Dialog sur toutes les pages
Section intitulée « Charger Dialog sur toutes les pages »Le code d’intégration étant responsable de l’initialisation de Dialog, il doit s’exécuter sur toutes les routes de la boutique, pas seulement sur les pages produit, listing et accueil. Deux éléments dépendent de la présence de Dialog sur la page :
- Les surfaces proactives (la modale et l’AI bar de Smart Discovery) n’apparaissent que là où Dialog est chargé : une configuration ciblant des pages de contenu ne se déclenche jamais si le SDK n’y est pas initialisé, même quand son motif d’URL correspond.
- Le tracking (sessions, ajout au panier, checkout) n’est capté que sur les pages où Dialog s’exécute : les routes sans Dialog perdent silencieusement leurs données analytiques.
Une erreur fréquente consiste à ne câbler l’initialisation que dans les flux produit, listing et accueil. Il est préférable d’initialiser Dialog globalement (par exemple dans un layout partagé ou un template racine), pour qu’il s’exécute sur tous les types de page.
Envoyer des messages
Section intitulée « Envoyer des messages »Avec contexte produit
Section intitulée « Avec contexte produit »client.sendProductMessage({ question: 'Est-ce que ce top taille petit ?', productId: 'product-123', productTitle: 'Top col V en lin', selectedVariantId: 'variant-456', // optionnel})Sans contexte produit
Section intitulée « Sans contexte produit »client.sendGenericMessage({ question: 'Quelle est votre politique de retour ?',})Récupérer des suggestions
Section intitulée « Récupérer des suggestions »Récupère la liste de suggestions générées par l’IA pour un produit donné. Utile si vous construisez une UI de suggestions custom sur votre PDP plutôt que d’utiliser notre composant DialogProductBlock.
const suggestions = await client.getSuggestions('product-123')// {// questions: [{ question: '...' }, ...],// assistantName: 'Your expert',// inputPlaceholder: 'Posez votre question...',// description: 'Posez n'importe quelle question sur ce produit'// }Informations de locale
Section intitulée « Informations de locale »const info = client.getLocalizationInformations()// { countryCode: 'FR', formatted: 'fr-FR', language: 'French', locale: 'fr' }Le SDK fait tourner Search de Dialog, la recherche par mots-clés sur votre catalogue. Les composants React et Vue et l’endpoint REST sont couverts dans le guide d’intégration de Search.
Noms d’index
Section intitulée « Noms d’index »Search lit un index par langue et par devise. Construisez les noms avec searchIndexName(index, language, currency) :
import { searchIndexName } from '@askdialog/dialog-sdk'
searchIndexName('products', 'fr', 'EUR') // 'products_fr_eur'index:'products','collections','articles'ou'pages'.language: code ISO 639-1 en minuscules ('fr'). Une locale régionale comme'fr-FR'lève une erreur.currency: code ISO 4217 ('EUR'), mis en minuscules dans le nom.
client.search()
Section intitulée « client.search() »client.search(request, options?) envoie une requête à l’API de recherche, telle quelle : pas de debounce, pas d’annulation des requêtes dépassées, pas d’analytics. Utilisez-la pour une recherche ponctuelle ; pour un champ de recherche, utilisez createSearchController.
const response = await client.search({ requests: [ { indexName: searchIndexName('products', 'fr', client.currency), query: 'chaussures de running', page: 0, // optionnel, commence à 0 (défaut 0) hitsPerPage: 20, // optionnel, de 1 à 100 (défaut 20) }, ],})// response.results[0].hits : [{ objectID, title?, url?, handle?, imageUrl?, priceRange? }]options.signal (un AbortSignal) annule la requête, qui est alors rejetée avec l’AbortError natif. Une erreur HTTP rejette avec DialogSearchError (status et message). Les champs de la requête et de la réponse sont détaillés dans la référence de l’endpoint REST.
createSearchController
Section intitulée « createSearchController »createSearchController(options) fait tourner une recherche interactive : il applique un debounce à la frappe, annule les requêtes dépassées et ignore leurs réponses tardives, pagine, relance, et enregistre les analytics de recherche (impressions et clics sur les résultats). Il n’affiche rien : vous vous abonnez à son état et affichez les résultats.
import { createSearchController, Dialog, SearchStatus } from '@askdialog/dialog-sdk'
const client = new Dialog({ apiKey: 'YOUR_PUBLIC_API_KEY', locale: 'fr-FR', currency: 'EUR' })
const controller = createSearchController({ search: (request, options) => client.search(request, options), language: 'fr', currency: client.currency, analytics: { surface: 'search_page', trackViewSearchResults: (params) => client.trackViewSearchResults(params), trackSelectSearchResult: (params) => client.trackSelectSearchResult(params), }, navigate: (url) => router.push(url), // optionnel sections: [{ index: 'collections', hitsPerPage: 5 }], // optionnel})
const unsubscribe = controller.subscribe((state) => { if (state.status === SearchStatus.SUCCESS) { renderCards(state.response.hits).forEach((card, index) => { controller.observeResult(card, index) card.onclick = (event) => { if (controller.selectResult(index)) event.preventDefault() } }) }})
input.oninput = () => controller.setQuery(input.value)form.onsubmit = (event) => { event.preventDefault() controller.submit(input.value)}nextButton.onclick = () => controller.setPage(controller.getState().page + 1)
// Au démontagecontroller.dispose()language est la partie ISO 639-1 de la locale du client ('fr' pour 'fr-FR') : passez-la explicitement, une locale régionale est refusée.
Les options sont figées à la création du controller : créez un nouveau controller pour changer de langue ou de devise.
| Option | Type | Requis | Défaut | Description |
|---|---|---|---|---|
search |
(request, options?) => Promise<SearchResponse> |
Oui | - | Envoie une requête. Passez client.search, lié au client, ou votre propre transport. |
language |
string |
Oui | - | Code ISO 639-1 en minuscules, par exemple 'fr'. |
currency |
string |
Oui | - | Code ISO 4217, par exemple client.currency. |
analytics |
SearchControllerAnalytics |
Oui | - | { surface, trackViewSearchResults, trackSelectSearchResult }. surface indique où les résultats s’affichent : 'search_page', 'autocomplete', 'smart_discovery' ou 'ai_bar'. Passez les méthodes trackViewSearchResults et trackSelectSearchResult du client. |
navigate |
(url, hit) => void |
Non | - | Adaptateur de routeur, appelé après l’enregistrement d’une sélection. Omettez-le pour laisser vos liens de résultats naviguer nativement. |
debounceMs |
number |
Non | 250 |
Debounce de frappe, en millisecondes. |
hitsPerPage |
number |
Non | 12 |
Produits par page. |
sections |
SearchSection[] ou () => SearchSection[] |
Non | [] |
Index supplémentaires cherchés avec les produits, par exemple [{ index: 'collections', hitsPerPage: 5 }]. Ne demandez qu’un index présent dans votre catalogue : un index absent fait échouer toute la recherche. |
Méthodes
Section intitulée « Méthodes »| Méthode | Description |
|---|---|
setQuery(query) |
Cherche après le délai de debounce. Une requête de moins de 2 caractères (après trim) remet l’état à idle. |
submit(query) |
Cherche immédiatement. |
setPage(page) |
Charge une page (à partir de 0) de la requête courante. Une nouvelle requête repart toujours de la page 0. |
retry() |
Rejoue la dernière requête, quand l’état est error. |
observeResult(element, index) |
Enregistre l’impression de state.response.hits[index] dès qu’element est visible. |
selectResult(index, options?) |
Enregistre le clic sur state.response.hits[index], puis appelle navigate. Renvoie true quand navigate a été appelé : appelez alors preventDefault() sur le clic. Passez { navigate: false } pour les clics molette et les clics avec modificateur. |
subscribe(listener) |
Appelle listener(state) à chaque changement d’état. Renvoie la fonction de désabonnement. |
getState() |
Renvoie l’état courant. |
dispose() |
Annule les requêtes en cours et retire listeners et observers. |
| Champ | Type | Description |
|---|---|---|
status |
'idle' | 'loading' | 'success' | 'empty' | 'error' |
empty est une recherche réussie sans résultat. Comparez avec les constantes SearchStatus. |
query |
string |
Dernière requête cherchée. |
page |
number |
Page (à partir de 0) de la dernière requête. |
response |
SearchResult |
Optionnel. Résultat produits : hits, nbHits, page, nbPages, hitsPerPage, query, queryID. Conservé pendant le chargement, vidé en cas d’erreur. |
sections |
object |
Optionnel. Résultats des index supplémentaires, par index (state.sections?.collections). |
error |
unknown |
Optionnel. L’erreur de la dernière requête, quand status vaut error. |
Tracking
Section intitulée « Tracking »Le SDK auto-tracke les interactions avec l’assistant (open / close / message / add-to-cart depuis l’assistant). Utilisez les méthodes ci-dessous pour les events qui se passent en dehors de l’assistant.
Add-to-cart et checkout manuels
Section intitulée « Add-to-cart et checkout manuels »client.registerAddToCartEvent({ productId: 'product-123', quantity: 1, currency: 'EUR', variantId: 'variant-456', price: 29.99,})
client.registerSubmitCheckoutEvent({ productId: 'product-123', quantity: 1, currency: 'EUR', variantId: 'variant-456',})Appelez ces méthodes à chaque fois que le client ajoute au panier ou termine son checkout sans passer par l’assistant Dialog, pour que le dashboard puisse attribuer la conversion correctement. Voir Tracking : SDK custom pour les détails.
Écouter les events de l’assistant
Section intitulée « Écouter les events de l’assistant »const unsubscribe = client.onAssistantEvent((event) => { // event.type, event.payload})
// Plus tardunsubscribe()Types d’events disponibles (guide complet dans Tracking : SDK custom) :
userOpenedAssistantuserClosedAssistantuserSentMessageuserClickedOnProductCarduserOpenedRecommendationuserAddedToCartuserSendPositiveFeedbackuserSendNegativeFeedback
Passez un objet theme à la construction :
const client = new Dialog({ apiKey: 'YOUR_PUBLIC_API_KEY', locale: 'fr', currency: 'EUR', theme: { backgroundColor: '#ffffff', primaryColor: '#000000', ctaTextColor: '#ffffff', ctaBorderType: 'rounded', // 'straight' | 'rounded' capitalizeCtas: false, fontFamily: 'Inter, sans-serif', highlightProductName: true, }, callbacks: { /* ... */ },})Les clés title, description et content du theme ne s’appliquent qu’aux composants Vue / React. Le SDK vanilla ne rend pas ces zones : c’est vous qui le faites.
Format SimplifiedProduct
Section intitulée « Format SimplifiedProduct »Votre callback getProduct doit renvoyer ce format :
interface SimplifiedProduct { id: string title: string handle: string descriptionHtml?: string url?: string totalInventory: number featuredImage?: { url?: string } | null variants: SimplifiedProductVariant[] options?: SimplifiedProductOption[]}
interface SimplifiedProductVariant { id: string displayName?: string inventoryQuantity?: number price: string // string, ex. '29.99' currencyCode: string // code ISO, ex. 'EUR' compareAtPrice?: string | null url?: string selectedOptions?: { name: string; value: string }[] image?: { url?: string } | null}
interface SimplifiedProductOption { id: string name: string position: number values: string[]}Étapes suivantes
Section intitulée « Étapes suivantes »- Composants React : UI drop-in avec le SDK.
- Composants Vue : pareil, pour Vue 3.
- Installer Search sur une storefront headless : Search avec le SDK, les composants ou l’endpoint REST.
- Tracking SDK custom : guide complet de tracking côté SDK.
- Problèmes d’ajout au panier : patterns de sync UI courants.
