Mettre en place le moteur de recherche Algolia
Si vous avez un site statique et que vous souhaitez mettre en place un moteur de recherche, vous allez soit devoir créer votre API, soit utiliser une solution externe.
J’ai de nombreuses fois vu des recherches sur des sites de documentations qui utilisaient Algolia, la curiosité m’a poussé à me créer un compte et le tester. Ils proposent une solution gratuite qui permet de faire jusqu’à 10K requêtes par mois, ce qui est parfait pour commencer. Voici les étapes et quelques pistes d’optimisations qui m’ont été utiles pour l’utiliser sur ce blog.
Créez votre compte et votre premier indexe
Se créer un compte sur Algolia est très simple, vous serez guidé sur tout le processus pour faire vos premières recherches.
Générer un fichier d’import
Vous avez plusieurs façons d’envoyer des données sur leur API, le plus
simple pour un site statique est de générer un json contenant l’ensemble
de vos articles à indexer. Si vous utilisez Hugo, créez un fichier
layouts/_default/list.algolia.json
et adaptez le contenu ci-dessous en
fonction de ce que vous souhaitez mettre à disposition pour la recherche.
{{ $.Scratch.Add "index" slice }}
{{ $section := $.Site.GetPage "section" .Section }}
{{ range .Site.AllPages }}
{{ if or (and (.IsDescendant $section) (and (not .Draft) (not .Params.private))) $section.IsHome }}
{{ $.Scratch.Add "index" (dict "objectID" .UniqueID "description" .Description "keywords" .Keywords "publishdate" .PublishDate "relpermalink" .RelPermalink "summary" .Summary "title" .Title "section" .Section "tags" .Params.Tags "categories" .Params.Categories "content" .Content) }}
{{ end }}
{{ end }}
{{ $.Scratch.Get "index" | jsonify }}
Si tout se passe bien, vous devriez pouvoir accéder à ce fichier algolia.json.
Envoyer les données vers Algolia
J’ai utilisé le module nodejs atomic-algolia pour envoyer les données dans l’indexe. Pour l’utiliser, ajoutez les variables d’environnement suivante pour qu’elles soient accessibles au moment du build :
ALGOLIA_INDEX_NAME
: le nom de l’index à rechercherALGOLIA_INDEX_FILE
: Le fichier contenant le json, probablement./public/algolia.json
ALGOLIA_ADMIN_KEY
: Votre admin key que vous trouverez dans l’admin AlgoliaALGOLIA_APP_ID
: Votre App ID que vous trouverez aussi dans l’admin Algolia
Et modifiez le script de build de cette façon :
$ hugo --minify && npm install -g atomic-algolia && atomic-algolia
Lancez un build de votre projet et l’ensemble de vos articles devraient remonter dans votre index 😎.
Intégrez le moteur de recherche sur votre site
C’est assez simple, il suffit de suivre les étapes de leur page d’installation.
Concernant le CSS, j’ai préféré le faire à ma sauce.
Petites optimisations
Surveiller les statistiques
Algolia propose des statistiques sur l’utilisation des recherche, notamment :
- les recherches les plus fréquentes
- Les recherches sans résultats
Ces données peuvent vous guider sur ce qu’attendent vos visiteurs du contenu de votre site 😉.
Séparez vos environnements
Pour éviter de “polluer” mes statistiques sur mes tests, j’ai créé deux indexes :
- julien.philippon.me.production
- julien.philippon.me.development
J’ai ensuite mis le nom de l’index dans un data-attribute, avec le dernier paramètre comprenant la variable d’environnement :
<body data-index="julien.philippon.me.{{ hugo.Environment }}">
...
</body>
Reste à intégrer l’index dans la configuration de instantsearch (je mets la production par défaut au cas où) :
const search = window.instantsearch({
indexName:
document.querySelector('body').dataset.index ||
'julien.philippon.me.production',
searchClient,
})
Pensez à modifier aussi la variable d’environnement ALGOLIA_INDEX_NAME
.
Économisez des crédits avec un “debounce”
Par défaut, les requêtes se font à chaque touche de clavier appuyé, ce qui entraine une consommation inutile. J’aimerai que la recherche se fasse uniquement une fois que la personne a fini de taper son mot.
Dans le widget searchBox, vous pouvez ajouter un “queryHook” qui va permettre de gérer cela, en jouant avec un setTimeout :
let timerId
window.instantsearch.widgets.searchBox({
container: '#searchbox',
queryHook(query, refine) {
clearTimeout(timerId)
timerId = setTimeout(() => refine(query), 500)
},
})
Ainsi, il faudra attendre 500 millisecondes sans qu’aucune touche ne soit actionnée avant de faire une requête.