Pagefind

Accueil de la documentation : barre latérale avec champ de recherche et version 1.5.2, liste des points forts à droite.

Un index de recherche déposé dans le dossier de sortie du site

Pagefind est une bibliothèque de recherche full-text pour sites statiques, écrite en Rust et publiée sous licence MIT. Une fois le build du générateur terminé, son binaire lit le HTML du dossier de sortie et y ajoute un dossier pagefind/ : l'index, découpé en fragments, et le JavaScript qui l'interroge dans le navigateur. Il n'y a pas de serveur de recherche à héberger : le site déployé reste un ensemble de fichiers.

Fragments chargés à la demande, réglages posés dans le HTML

  • Charge réseau : d'après la documentation, une recherche sur un site de 10 000 pages charge moins de 300 Ko au total, bibliothèque comprise, et plutôt 100 Ko sur la plupart des sites. Le navigateur ne récupère que les fragments utiles à la requête, que la 1.5.0 a allégés d'environ 45 %.
  • Réglages dans les gabarits : les attributs data-pagefind-* (body, ignore, meta, filter, sort) délimitent le contenu indexé et déclarent métadonnées, facettes et clés de tri.
  • Un index par langue : Pagefind lit l'attribut lang de <html>, indexe chaque langue à part et ne cherche que dans celle de la page affichée, avec la racinisation propre à la langue quand elle est prise en charge, français compris.
  • Accents tolérés : depuis la 1.5.0, « cafe » trouve « café » et la graphie exacte passe en tête. L'option exactDiacritics: true rétablit la correspondance stricte.
  • Résultats par section : chaque titre h1 à h6 doté d'un id devient un sous-résultat qui mène à l'ancre de la section.
  • Interface en web components : la 1.5.0 a ajouté des éléments <pagefind-*> (fenêtre modale, champ à liste déroulante, filtres), réglables par variables CSS et traduits selon la langue de la page. Une API JavaScript reste disponible pour une interface maison.

Générateurs statiques, PDF et recherche entre domaines

  • Ajouter la recherche à un site Hugo, Zola, Astro ou Eleventy : la page des ressources communautaires recense un guide ou une intégration pour chacun.
  • Indexer des PDF ou des sous-titres par l'API Node ou Python : addCustomRecord attend une URL, une langue et le texte brut, que le script doit extraire lui-même.
  • Chercher dans un blog et dans sa documentation logés sur deux domaines : mergeIndex fusionne les index dans le navigateur, si l'autre domaine envoie les en-têtes CORS.

Indexation à chaque build, WebAssembly à autoriser dans la CSP

L'index se construit sur le HTML final. Sous hugo serve ou un autre serveur de développement, la recherche n'apparaît pas tant que Pagefind n'a pas indexé le dossier de sortie. La commande prend donc place dans la chaîne de déploiement, après chaque build.

Une politique CSP stricte bloque la recherche. La documentation demande d'autoriser script-src 'wasm-unsafe-eval' pour le WebAssembly et, si les workers sont restreints, worker-src 'self' blob:. L'option noWorker: true ramène la recherche sur le fil principal.

Un seul data-pagefind-body restreint tout le site. Dès qu'une page porte l'attribut, toutes celles qui ne le portent pas sortent de l'index, page d'accueil comprise.

Le chinois, le japonais et le coréen passent par la version étendue. Le binaire pagefind_extended, plus lourd, segmente ces langues sans racinisation ; npx pagefind le télécharge d'office, pip le demande avec pagefind[extended]. Le tchèque, l'ukrainien ou le vietnamien n'ont pas de racinisation non plus : une recherche n'y rapproche pas les formes d'un même mot.

Le projet vise les sites de plusieurs dizaines de milliers de pages. C'est l'objectif affiché par la documentation, qui renvoie à des démos sur MDN, Godot et XKCD. Pagefind n'a aucun composant serveur : --serve lance seulement un serveur statique de prévisualisation.

La dernière version est la v1.5.2, du 12 avril 2026. Le projet est en 1.x depuis septembre 2023 et le dernier commit date du 26 octobre 2026. L'ancienne interface (Default UI et Modular UI) reste prise en charge « pour l'instant », selon les notes de la 1.5.0.