4 minutes
Installer une barre de recherche Algolia sur son blog
Introduction
L’objectif de cet article est de voir comment installer un moteur de recherche Algolia sur son blog Hugo pour pouvoir rechercher n’importe quel contenu.
Le résultat final sur mon blog:
Création de compte Algolia
La première chose à faire est de créer un compte Algolia.
Vous pouvez souscrire à un plan community. Cela vous permettra de créer une barre de recherche gratuitement.
Créer une application.
Créer ensuite un indice. Un indice peut contenir un ou plusieurs indexes.
Enfin créer un index.
Dans l’onglet API Keys, récupérez l’Application ID
et l’Admin API Key
.
Indexation du contenu du blog
Nous allons utiliser une librairie NodeJS appelée atomic-algolia
permettant de générer et d’envoyer des indices Hugo sur Algolia.
Voici donc les commandes à exécuter dans le dossier racine de votre blog Hugo:
npm install atomic-algolia --save
npm init
Ajouter la ligne suivante dans la section scripts
du fichier package.json
:
"algolia": "atomic-algolia"
Créer un fichier .env
et renseigner les variables d’environnement suivantes:
ALGOLIA_APP_ID=YOUR_APPLICATION_ID
ALGOLIA_ADMIN_KEY=YOUR_ADMIN_API_KEY
ALGOLIA_INDEX_NAME=YOUR_INDEX_NAME
ALGOLIA_INDEX_FILE=public/algolia.json
Générer le fichier json d’indexation de contenu de votre blog et envoyer le sur Algolia:
npm run algolia
Création de la barre de recherche
Nous allons maintenant voir comment ajouter une barre de recherche sur son site.
Voici le code source de la barre de recherche sur mon site:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/instantsearch.js/1/instantsearch.min.js"></script>
<style>
.nav-search {
-webkit-flex-grow: 1;
-ms-flex-positive: 1;
position: relative;
width: 90%;
height: 47px;
margin-top: 20px;
background-color: white;
z-index: 1000;
}
.nav-search.active {
box-shadow: 0 4px 4px rgba(79, 79, 79, 0.21);
}
.nav-search.active .search-dropdown {
display: block;
}
.nav-search.active .search-input {
-webkit-animation: expand-search-box-animation 0.5s forwards;
animation: expand-search-box-animation 0.5s forwards;
}
.nav-search.active .search-input input {
border-width: 2px;
}
.nav-search.active .search-input .close-search {
display: inline-block;
}
.nav-search.active .search-input .search-dropdown {
display: block;
}
.nav-search .search-input {
transition: left 0.2s ease-in-out;
transition: width 0s ease-in-out;
}
.nav-search .search-input .search-icon {
position: absolute;
left: 15px;
top: 13px;
z-index: 999;
color: black;
}
.nav-search .search-input input {
font: 16px/1.875 "Avenir Next W01", "Avenir Next", "Helvetica Neue", Helvetica, sans-serif;
height: 50px;
border: 1px solid #1b98f4;
border-radius: 4px;
min-width: 200px;
width: 100%;
padding-left: 50px;
background-color: white;
}
.nav-search .search-input input:focus {
outline: none;
}
.nav-search .search-input i.close-search {
color: #1b98f4;
display: none;
position: absolute;
right: 15px;
top: 13px;
cursor: pointer;
}
.search-dropdown {
box-sizing: border-box;
color: #B3B3B3;
font: 14px/1.875 "Avenir Next W01", "Avenir Next", "Helvetica Neue", Helvetica, sans-serif;
opacity: 1.00;
padding: 20px;
width: 100%;
-webkit-animation: expand-search-dropdown-animation 0.5s forwards;
animation: expand-search-dropdown-animation 0.5s forwards;
overflow-y: scroll;
max-height: 400px;
border-radius: 0 0 4px 4px;
background-color: #FCFCFC;
border: 1px solid #E0E0E0;
box-shadow: 1px 3px 4px rgba(0, 0, 0, 0.09);
display: none;
background-color: white;
}
.search-dropdown .small {
-webkit-flex-basis: 35%;
-ms-flex-preferred-size: 35%;
flex-basis: 35%;
}
.search-dropdown .search-section .hits-blank {
color: #666;
text-align: center;
padding-top: 20px;
}
.search-dropdown a {
text-decoration: none;
color: inherit;
z-index: 2000;
}
.hit {
border-bottom: 1px solid #E6E6E6;
margin-bottom: 20px;
}
.hit .hit-title {
color: #1b98f4;
font-family: 'bt_mono', monospace;
font-weight: 500;
margin-bottom: 0;
margin-top: 0;
display: inline-block;
font-size: 14px;
}
.hit .hit-description {
text-decoration: none;
color: black;
font-size: 14px;
display: block;
margin-top: 3px;
}
.hit .hit-anchor {
font-size: 13px;
color: #666;
}
.hit .algolia-docsearch-suggestion--highlight {
background-color: #FFE9A4;
}
.ais-hits--item:last-child .hit {
border: 0;
}
</style>
<script>
$(function() {
$('#search-input').on('keyup', function() {
$('.nav-search').addClass('active');
$('#hits-container').scrollTop(0);
})
$('.close-search').on('click', function(evt) {
evt.preventDefault();
$('#search-input').val('');
$('.nav-search').removeClass('active');
})
$('#search-input').on('blur', function(evt) {
if(!evt.isDefaultPrevented) {
$('.nav-search').removeClass('active');
}
})
let search = instantsearch({
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_READONLY_API_KEY',
indexName: 'YOUR_SEARCH_INDEX',
searchParameters: {replaceSynonymsInHighlight: false},
searchFunction: function(helper) {
var searchResults = $('.search-results');
if (helper.state.query === '') {
searchResults.hide();
return;
}
helper.search();
searchResults.show();
}
});
// add a searchBox widget
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-input',
placeholder: 'Search for libraries in France...'
})
);
// add a hits widget
search.addWidget(
instantsearch.widgets.hits({
container: '#hits-container',
hitsPerPage: 10,
debug: true,
templates: {
item: '<a href="\{\{url\}\}" target="_blank"><div class="hit"><div class="hit-content"><h2 class="hit-title">\{\{\{_highlightResult.title.value\}\}\}</h2><br><small>\{\{lvl0\}\} \{\{#lvl1\}\}> \{\{\{_highlightResult.lvl1.value\}\}\} \{\{/lvl1\}\}\{\{#lvl2\}\}> \{\{\{_highlightResult.lvl1.value\}\}\} \{\{/lvl2\}\}\{\{#lvl3\}\}> \{\{\{_highlightResult.lvl3.value\}\}\} \{\{/lvl3\}\} \{\{#lvl4\}\}> \{\{\{_highlightResult.lvl4.value\}\}\}\{\{/lvl4\}\}</small><p class="hit-description">\{\{\{_snippetResult.content.value\}\}\}</p></div></div></a>',
empty: '<div id="no-results-message"> <p>We didn`t find any results for the search <em>"\{\{query\}\}"</em>.</p></div>'
}
})
);
// start
search.start();
});
</script>
Pour que votre index soit utilisé, il suffit de remplacer la valeur des variables appId: 'YOUR_APPLICATION_ID'
, apiKey: 'YOUR_READONLY_API_KEY'
et indexName: 'YOUR_SEARCH_INDEX'
dans le code ci-dessous par les votres.
Algolia est un très bon service SAAS que je recommande. Il est excessivement intuitif et vraiment très performant.