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) danspublic/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 dedata-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
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 |
|---|---|
| Avant | 14/20 |
| Préchauffage de l'index | 16/20 |
| + variantes d'orthographe | 18/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.