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.

Installer Search sur une storefront headless

Cette page installe Search sur une storefront qui n’est pas un thème Shopify : un front headless, un site custom, ou toute stack dont vous écrivez vous-même le frontend. Sur un thème Shopify, suivez plutôt Installer Search sur Shopify.

Search est une recherche par mots-clés sur votre catalogue Dialog : elle compare les mots de la requête à vos produits, avec tolérance aux fautes de frappe, synonymes et produits épinglés. Vous avez trois façons de la brancher, de la plus prête à l’emploi à la plus libre :

Option À utiliser quand
Composants React ou Vue Votre storefront tourne sous React ou Vue 3 : une barre de recherche et un panneau de résultats, prêts à intégrer.
Search controller du SDK Tout autre framework ou du JS vanilla : le SDK exécute la recherche, vous affichez les résultats.
API REST Vous appelez Search depuis votre propre serveur ou client, sans le SDK.
  • Votre clé API publique : chaque option s’authentifie avec la clé API publique Dialog. Consultez Où trouver vos clés API. N’utilisez jamais la clé privée dans une storefront.
  • Votre catalogue dans Dialog : Search renvoie les produits de votre catalogue Dialog. Vérifiez d’abord qu’il est synchronisé (Intégration du catalogue).
  • Une langue et une devise : un code langue ISO 639-1 (fr) et une devise ISO 4217 (EUR). Search tient un index par langue et par devise ; une locale régionale comme fr-FR est refusée comme langue.

@askdialog/dialog-react et @askdialog/dialog-vue fournissent une barre de recherche (DialogSearchBar) et un panneau de résultats (DialogSearchResults) par-dessus le search controller du SDK : useDialogSearch({ client, language, currency }) crée le controller, les deux composants l’affichent. Le panneau affiche les produits (et les collections, si vous les demandez), met en évidence la correspondance avec la requête dans chaque titre et pagine.

L’exemple de code et la référence complète du hook et des composants (options, props, adaptateur de routeur, colonne des collections) se trouvent avec chaque package :

En dehors de React et Vue, utilisez createSearchController de @askdialog/dialog-sdk. Le controller envoie les requêtes et tient l’état de la recherche ; vous affichez les résultats à partir de cet état.

import { createSearchController, Dialog } 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),
},
})
controller.subscribe((state) => render(state)) // votre rendu
input.oninput = () => controller.setQuery(input.value)

La référence SDK : createSearchController donne le câblage complet (impressions, clics, pagination), les options, les méthodes et l’état.

Le SDK et les composants appellent l’endpoint POST /public/search/lexical. Appelez-le directement quand vous n’utilisez pas le SDK, par exemple depuis votre propre serveur.

POST https://api.askdialog.ai/public/search/lexical
Content-Type: application/json
x-dialog-api-key: YOUR_PUBLIC_API_KEY

Envoyez votre clé API publique dans le header x-dialog-api-key. Une requête sans clé, ou avec une clé inconnue, répond 401.

L’endpoint est limité par adresse IP : 20 requêtes par seconde. Au-delà, il répond 429 avec un header Retry-After.

Le body contient une entrée par index à chercher, dans requests (de 1 à 10 entrées). Toutes les entrées doivent partager la même query, la même langue et la même devise.

{
"requests": [
{ "indexName": "products_fr_eur", "query": "chaussures de running", "page": 0, "hitsPerPage": 20 },
{ "indexName": "collections_fr_eur", "query": "chaussures de running", "hitsPerPage": 5 }
]
}
Champ Type Requis Description
indexName string Oui <index>_<langue>_<devise>. <index> vaut products, collections, articles ou pages ; la devise est en minuscules (products_fr_eur). Ne demandez qu’un index présent dans votre catalogue : un index absent fait échouer toute la requête.
query string Oui La requête du visiteur : de 2 à 200 caractères, après trim.
page number Non Page, à partir de 0. Défaut 0.
hitsPerPage number Non Résultats par page, de 1 à 100. Défaut 20.
facetFilters array Non Filtres sur des valeurs, sur les entrées products uniquement. Voir Filtres.
numericFilters array Non Filtres sur des nombres, sur les entrées products uniquement. Voir Filtres.

Un champ inconnu dans le body ou dans une entrée répond 400.

Les filtres restreignent une entrée products sur les attributs filtrables de votre catalogue, ceux que vous publiez dans Filtres produits : un filtre sur un autre attribut répond 400. Les deux champs sont une liste de groupes : les groupes se combinent en ET, les filtres d’un même groupe en OU.

{
"indexName": "products_fr_eur",
"query": "veste",
"facetFilters": [[{ "attribute": "color", "value": "noir" }, { "attribute": "color", "value": "marine" }]],
"numericFilters": [[{ "attribute": "price", "from": 50, "to": 150 }]]
}
  • Un filtre de facette s’écrit { attribute, value, negated? }. Passez negated: true pour exclure la valeur.
  • Un filtre numérique s’écrit soit { attribute, operator, value }, avec operator parmi <, <=, =, !=, >=, >, soit en intervalle { attribute, from, to }.

La réponse contient un résultat par entrée, dans results, dans l’ordre de la requête.

{
"results": [
{
"index": "products_fr_eur",
"hits": [
{
"objectID": "product-123",
"title": "Chaussures de trail",
"url": "https://maboutique.fr/products/chaussures-de-trail",
"handle": "chaussures-de-trail",
"imageUrl": "https://cdn.maboutique.fr/trail.jpg",
"priceRange": {
"min": { "amount": "89.90", "currencyCode": "EUR" },
"max": { "amount": "99.90", "currencyCode": "EUR" }
}
}
],
"nbHits": 42,
"page": 0,
"nbPages": 3,
"hitsPerPage": 20,
"processingTimeMS": 12,
"query": "chaussures de running",
"queryID": "5f0c..."
}
]
}

Chaque résultat :

Champ Type Description
index string L’indexName de l’entrée.
hits array Les enregistrements de cette page.
nbHits number Nombre total de correspondances, toutes pages comprises.
page number Page renvoyée, à partir de 0.
nbPages number Nombre de pages.
hitsPerPage number Taille de page appliquée.
processingTimeMS number Durée de la recherche, en millisecondes.
query string La requête cherchée.
queryID string Identifiant de cette recherche, un par entrée.
filters array Optionnel : les filtres appliqués à l’entrée, un bloc par source.

Chaque hit porte objectID (l’identifiant de l’enregistrement) et, quand ils sont connus, ses champs d’affichage : title, url, handle, imageUrl, et pour les produits un priceRange (min et max, chacun avec un amount en chaîne décimale comme "24.90" et un currencyCode optionnel).

Les hits produits peuvent aussi porter leurs données d’achat, toutes optionnelles :

Champ Type Description
totalVariants number Nombre de variantes.
tracksInventory boolean Le produit suit-il son stock.
totalInventory number Stock cumulé des variantes.
options array Options du produit : { name, values }.
variants array Variantes : id, title, url, imageUrl, price, compareAtPrice, inventoryQuantity, inventoryPolicy, selectedOptions ({ name, value }).

Le stock d’une variante n’est pas stocké sous forme de booléen : déduisez-le de inventoryQuantity et inventoryPolicy, au regard du tracksInventory du produit.

Statut Cause
400 Body invalide : champ inconnu, requête de moins de 2 caractères, entrées avec des requêtes, langues ou devises différentes, ou filtre sur un attribut non filtrable.
401 Clé API publique absente ou inconnue.
404 Nom d’index inexistant, par exemple un nom mal formé ou sans suffixe de devise (products_fr).
429 Limite de débit atteinte : réessayez après le délai Retry-After.
502, 503, 504 Search est momentanément indisponible : réessayez plus tard.

Les bodies d’erreur portent un statusCode et un message.

Sur votre storefront :

  1. Tapez un nom de produit dans votre champ de recherche : des produits Dialog apparaissent.
  2. Tapez-le avec une faute de frappe : les bons produits apparaissent toujours.
  3. Cliquez sur un résultat : sa page produit s’ouvre.
  4. Changez de page avec la pagination : les résultats suivants se chargent.

Si aucun résultat n’apparaît jamais, vérifiez votre clé API publique et la synchronisation de votre catalogue, puis l’onglet réseau : un 404 désigne le nom d’index, un 401 la clé.