Aller au contenu

Demander à la doc

Les réponses viennent uniquement de cette documentation, sources à l’appui. Pour les sujets propres à votre compte, la doc vous oriente vers le bon interlocuteur.

Que cherchez-vous ?

Vous discutez avec un assistant IA. Il peut se tromper, pensez à vérifier les informations importantes.

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 :

Fenêtre de terminal
npm install @askdialog/dialog-sdk
# ou
pnpm add @askdialog/dialog-sdk
# ou
yarn add @askdialog/dialog-sdk

Depuis 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.

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
},
},
})
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.

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.addToCart n’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).

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 update Google Consent Mode à denied, ou OneTrust chargé sans le groupe performance (C0002), désactive l’analytics pour ce visiteur ;
  • window.dialog.audit.consent indique detectedCmp: '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.

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 optionnel
client.clearCurrentProduct() // sortie vers une page non-produit

L’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.

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.

client.sendProductMessage({
question: 'Est-ce que ce top taille petit ?',
productId: 'product-123',
productTitle: 'Top col V en lin',
selectedVariantId: 'variant-456', // optionnel
})
client.sendGenericMessage({
question: 'Quelle est votre politique de retour ?',
})

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'
// }
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.

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(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(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émontage
controller.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é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.

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.

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.

const unsubscribe = client.onAssistantEvent((event) => {
// event.type, event.payload
})
// Plus tard
unsubscribe()

Types d’events disponibles (guide complet dans Tracking : SDK custom) :

  • userOpenedAssistant
  • userClosedAssistant
  • userSentMessage
  • userClickedOnProductCard
  • userOpenedRecommendation
  • userAddedToCart
  • userSendPositiveFeedback
  • userSendNegativeFeedback

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.

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[]
}