Plugin flexweg-search
Le plugin ajoute une recherche full-text côté client à votre site public. Il génère un index JSON au moment de la publication et ship un petit script runtime qui ouvre une modale de recherche partout
Le plugin flexweg-search ajoute une recherche full-text côté client à votre site public. Il génère un index JSON au moment de la publication et ship un petit script runtime qui ouvre une modale de recherche partout où votre thème expose un trigger [data-cms-search].
Pas de serveur, pas de service tiers — fonctionne très bien jusqu'à ~5 000 posts. Pour des sites plus gros, considérez Algolia ou similaire via du custom code.
Ce qu'il génère
| Fichier | Path sur Flexweg | Objet |
|---|---|---|
search-index.json |
/search-index.json |
L'index — titre, slug, extrait, catégorie, tags, date pour chaque post en ligne |
search.js |
/search.js |
Script runtime : ouvre la modale, filtre l'index, rend les résultats |
Le runtime est bundlé dans la source du plugin comme search-runtime.js et importé via ?raw. Donc search.js est un fichier vanilla-JS self-contained unique — pas de dépendances externes, pas de loading modulaire.
Réglages
/settings/plugin/flexweg-search expose :
- Champs indexés — checkbox par champ : titre, slug, extrait, catégorie principale, tags, contenu (la dernière est coûteuse car elle indexe le body markdown entier — 50% du temps de génération).
- Limite de résultats — combien de résultats afficher dans la modale (défaut 10).
- Substring search vs whole-word — fuzziness du matching.
- Force regenerate — re-construit
search-index.json+ ré-uploadsearch.js.
Le hook lifecycle
Sur publish.complete, post.unpublished, post.deleted, le plugin re-construit toujours l'index complet (pas incremental — ce serait plus complexe que la valeur). Le temps de génération scale linéairement avec le nombre de posts.
Pour un site de 100 posts : ~50 ms. Pour 1000 posts : ~500 ms. Pour 5000 posts : ~2-3 s.
Comment ouvrir la modale
Le thème expose un trigger via [data-cms-search] :
<button data-cms-search class="search-trigger">
<span class="material-symbols-outlined">search</span>
</button>
Le search.js runtime, chargé sur chaque page via <script defer src="/search.js">, écoute les clicks sur ces triggers et ouvre la modale.
Si votre thème n'expose pas de trigger, le runtime ne sert à rien — pas de modale possible. Les thèmes intégrés (default, magazine, corporate, marketplace-core) exposent un trigger dans leur header.
UX de la modale
- Input de recherche en haut
- Liste de résultats en temps réel (filtre à chaque keystroke)
- Click sur un résultat ouvre la page correspondante
- ESC ferme la modale
- Keyboard arrow ↑↓ navigue les résultats, Enter sélectionne
Les résultats sont rendus en HTML simple — vous pouvez customiser via CSS spécifique à votre thème.
Performance et taille
search-index.json pour 1000 posts (titre + slug + extrait indexés) : ~150 Ko gzippé. Pour 5000 posts : ~600 Ko gzippé.
Le runtime search.js : ~3 Ko gzippé.
Au premier ouverture de la modale, le navigateur fetch l'index. Sur des connexions lentes (3G), ça peut prendre ~500 ms pour un site moyen. Le runtime cache l'index en mémoire pour les recherches suivantes.
Champs contentMarkdown : à utiliser avec parcimonie
Activer l'indexation du contentMarkdown :
- Multiplie la taille de l'index par ~5-10
- Permet de trouver des posts par n'importe quel mot du corps
Pour un blog éditorial, ça peut valoir le coup. Pour un site corporate / vitrine, c'est probablement overkill — un index sur titre + extrait suffit.
Désactivation
Désactiver le plugin ne supprime PAS les fichiers existants. Pour purger : désactivez, puis supprimez /search-index.json et /search.js manuellement.
À l'inverse, garder le runtime sans actualiser l'index est OK — le runtime affiche les résultats stales jusqu'au prochain Force regenerate.
Limitations
- Pas de scoring de pertinence avancé — c'est du substring matching basique
- Pas de typo tolerance — taper "compagny" ne trouve pas "company"
- Pas de filtres par catégorie dans la modale (juste un input)
- Pas de pagination — limité aux N premiers résultats
Pour ces fonctionnalités, considérez un service externe (Algolia, MeiliSearch, Typesense) via du custom code.
Cas multilang
flexweg-search n'a pas (encore) d'intégration native avec flexweg-multilang. L'index inclut les posts dans toutes les langues — donc une recherche peut retourner des résultats dans une langue que l'utilisateur ne comprend pas.
Pour un support multilang propre, c'est une amélioration future (générer un index par langue + filtrer par la langue courante côté runtime).