Décisions

ADR 009 : Recherche Pagefind en version 1

Statut

Accepté (24/10/2026), remplace ADR 004

Contexte

La vitrine publie quelques centaines de structures, quelques milliers de personnes et projets, toutes en pages statiques. Les publications ne sont pas republiées. scanR utilise Elasticsearch ; le site d'audit, Pagefind.

Décision

  • Pagefind indexe, après next build, le HTML des fiches générées (.next-<instance>/server/app) dans public/pagefind/<instance>/. La recherche s'exécute dans le navigateur (src/features/search/PagefindSearch.tsx), sans serveur ni service à superviser.
  • Seul le contenu marqué data-pagefind-body (les fiches) est indexé ; les filtres viennent de data-pagefind-filter (type, groupe).
  • Sans filtre, les 5 premières structures sont affichées en tête des résultats : sans cela, les milliers de fiches de projets et de chercheurs, plus courtes, masquent les laboratoires (requêtes de référence : 0/20 → 17/20 à Saclay).
  • Sans JavaScript, les listes (structures par groupe, thématiques, index alphabétique des chercheurs) restent navigables.
  • L'issue de chaque recherche (résultats ou non) remonte en métrique agrégée (/api/telemetry) et dans Matomo (trackSiteSearch).
  • Bascule vers Meilisearch si l'un de ces besoins apparaît : mise à jour sans reconstruction, tolérance aux fautes, recherche d'expertise sémantique.

Deux comportements de Pagefind 1.4.0, mesurés le 26/10/2026

Les deux ont été trouvés en instruisant un score de 14/20 attribué à tort à la racinisation. Ils sont contournés dans src/features/search/PagefindSearch.tsx (warmUp, queryVariants, searchAll), et le script d'évaluation applique le même traitement — mesurer autrement décrirait un comportement que personne ne rencontre.

L'index répond avant d'être complètement chargé

À froid, pagefind.search('biologie') renvoie 6 fiches de laboratoire. Après un preload('biolog'), la même requête en renvoie 88, dont celles qui manquaient. L'ordre des requêtes change donc le résultat :

Code
biologie=6 biolog=88 biologie=88 biologique=88 biologie=88

Comme une requête à plusieurs mots exige tous les termes, un seul terme sous-chargé vide le résultat : « biologie des plantes » ne renvoyait rien alors que l'IPS2 répond aux deux mots. Correctif : précharger un préfixe de chaque terme avant de chercher.

Les accents ne sont pas repliés, et le trait d'union coupe

« écologie » et « ecologie » sont deux mots distincts de l'index — 12 fiches contre 31 — et « humain-machine » ne trouve pas ce que trouve « humain machine ». Les deux orthographes étant également légitimes au clavier, la requête est déclinée en quatre variantes (telle quelle, sans trait d'union, sans accents, les deux) et les résultats sont fusionnés par identifiant de page, au meilleur score.

Effet mesuré

Jeu de requêtes de référence (Saclay)Score
Avant14/20
Préchauffage de l'index16/20
+ variantes d'orthographe18/20

Les deux échecs restants ne sont pas des défauts de l'outil : « physique des particules » et « droit des affaires numérique » ne figurent pas dans le vocabulaire des fiches visées (IJCLab, DANTE). Les corriger demanderait d'enrichir les fiches, pas de régler la recherche — et le jeu de requêtes ne doit pas être ajusté pour faire monter le score.

Conséquences

  • L'index se reconstruit à chaque build : la fraîcheur de la recherche suit celle du site.
  • Pas de tolérance aux fautes avancée ; la racinisation française de Pagefind couvre les pluriels et variantes simples, mais ni les accents ni le trait d'union (voir ci-dessus).
  • Chaque recherche coûte jusqu'à quatre requêtes Pagefind et quelques préchargements d'index : c'est le prix des deux contournements, et il est payé dans le navigateur.