Een goede zoekfunctie aan een website toevoegen is altijd moeilijk, maar voor statische websites zijn degelijke opties dun gezaaid. Pagefind brengt daar verandering in en maakt het heel eenvoudig! Het is al aan deze site toegevoegd, dus klik voor een korte demonstratie op het zoekicoon in de navigatiebalk bovenaan deze pagina. Wil je zelf een vergelijkbare zoekfunctie aan een website toevoegen, lees dan verder.

Het idee achter Pagefind is opmerkelijk eenvoudig. Je neemt een stukje CSS en JavaScript van hun site op en genereert de website zoals gewoonlijk. Voor je hem uploadt, voer je echter Pagefind uit. Dat doorzoekt je gegenereerde pagina’s en maakt een index die het toegevoegde stukje JavaScript gebruikt om relevante pagina’s te vinden op basis van de opgegeven zoektermen. Publiceer de statische pagina’s samen met de index die Pagefind maakte, en klaar.

Pagefind installeren en aan de slag gaan

Er zijn enkele opties beschikbaar die je in de documentatie van Pagefind vindt. Op mijn systeem (Windows 10) werkte het uitvoeren via [npx] niet, dus koos ik voor de binaire versie.

Voor deze website wordt de releaseversie in de map ./docs (de bronmap) gegenereerd. Daar kun je op GitHub eenvoudig een website van maken. Daarom moest een .yaml-bestand, pagefind.yaml, worden toegevoegd om Pagefind naar de juiste map te verwijzen en aan te geven waar de uitvoer moet komen. Ik koos ervoor die uitvoer in een map pagefind op te slaan (opgelet: deze map wordt een submap van je bronmap). Het yaml-bestand zie je hieronder.

# pagefind.yaml
source: docs
bundle_dir: pagefind

Vervolgens werd een regel toegevoegd aan het batchscript waarmee deze website opnieuw wordt opgebouwd. Pagefind moet worden uitgevoerd nadat de website is gegenereerd, zodat het de recentste versie van de bestanden kan indexeren. (Opmerking: het binaire bestand van Pagefind staat in dezelfde map als dit script, die ook de hoofdmap van de repository is.)

bundle exec jekyll build --config _config.yml && ^
.\pagefind.exe

Telkens wanneer het batchbestand de website genereert, wordt voortaan ook de zoekindex bijgewerkt.

Het sjabloon bijwerken

De officiële documentatie is hierover uitstekend! Je moet één CSS-bestand en één JS-script aan de head van je site toevoegen. Pas dit aan volgens het pad waar Pagefind de index opslaat en de manier waarop je CSS verwerkt (hier wordt bijvoorbeeld de basis-URL toegevoegd).

<link rel="stylesheet" href="/pagefind/pagefind-ui.css">
<script src="/pagefind/pagefind-ui.js" type="text/javascript"></script>

De zoekbalk toevoegen

Hier wijkt deze site af van de officiële documentatie: wanneer je op de zoekknop klikt, verschijnt een modaal venster met de zoekbalk. Modale vensters zijn eigenlijk verborgen divs onderaan elke pagina die met JavaScript naar de voorgrond worden gebracht. Het onderstaande fragment is de HTML-code voor het modale venster dat hier wordt gebruikt. De code staat onderaan elke pagina en kan met Micromodal worden weergegeven.

<div class="modal micromodal-slide" id="modal-2" aria-hidden="true">
	<div class="modal__overlay" tabindex="-1" data-micromodal-close>
		<div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-2-title">
			<header class="modal__header">
				<h2 class="modal__title" id="modal-2-title">
					Search
				</h2>
			</header>
			<main class="modal__content" id="modal-2-content">
				<div id="search"></div>
			</main>
			<footer class="modal__footer">
					<button class="modal__btn modal__btn-primary" data-micromodal-close="" aria-label="Close this dialog window">Close</button>
			</footer>
		</div>
	</div>
</div>

Er is maar een klein stukje JavaScript nodig om het modale venster te tonen wanneer je op het zoekicoon klikt en de focus op het zoekveld te zetten. Zoals je hieronder ziet, is dat vrij eenvoudig. Het moeilijkste is uitzoeken welke klassen Pagefind toewijst aan de elementen die het toevoegt (.pagefind-ui__search-input is bijvoorbeeld het tekstvak waarin de zoekterm wordt ingevoerd).

<script type="text/javascript">
$(document).ready(function() {
	MicroModal.init();

	$('.nav-link-search').click(function(ev) {
	  ev.preventDefault();

	  MicroModal.show('modal-2', {
	  		onClose: function() { $('.nav-link-contact').blur(); },
	  		disableFocus: true
	  });

	  document.querySelector('.pagefind-ui__search-input').focus();
	});

});
</script>

Nu zou alles moeten werken! Er was nog wat CSS nodig om alles mooi op elkaar af te stemmen, maar de resultaten zijn geweldig!

Zoekresultaten op deze website. De zoekfunctie is gemaakt met Pagefind en wordt weergegeven in een Micromodal

De afbeeldingen in orde brengen

Omdat er voor elke post een miniatuurafbeelding beschikbaar is, is het logisch om die in de resultaten te tonen. Daarvoor werd een kleine kunstgreep gebruikt. Helemaal aan het begin van elke postpagina wordt de miniatuurafbeelding opgenomen, maar niet getoond. Door het juiste attribuut toe te voegen, gebruikt Pagefind die afbeelding in de resultaten.

<img data-pagefind-meta="image[src]" src="/assets/images/thumbnails/search_header.jpg" style="display:none" />

Sommige onderdelen uitsluiten

Sommige pagina’s zijn niet relevant als zoekresultaat. Pagina’s met bijvoorbeeld een lijst van posts met een bepaalde tag maken de resultaten alleen maar rommeliger. Ook links naar vorige en volgende posts moeten uit de index worden gehouden. Gelukkig is dit heel eenvoudig: zoek de onderdelen die bij het indexeren moeten worden overgeslagen en voeg het attribuut data-pagefind-ignore toe. Mogelijk moet je enkele keren testen om alle plekken te vinden die moeten worden uitgesloten, maar de zoekresultaten worden er beter van en dat is de moeite meer dan waard.

Conclusie

Vroeger was een zoekfunctie aan een statische website toevoegen omslachtig en kostte de ontwikkeling ervan veel tijd. Naarmate deze website groeide, werd het echter steeds moeilijker om specifieke posts via het overzicht en de tags terug te vinden. Een degelijke zoekfunctie werd dus onmisbaar. Met Pagefind was dit een relatief eenvoudig proces dat in één avond klaar was. Tegenwoordig is er echt geen excuus meer om geen zoekfunctie aan je statische websites toe te voegen!

Header door Markus Winkler op Unsplash