Client-Side Search for a Static Site
implementationPart of Statically generated sites
A static site has no server to run a search query, yet readers still expect to search it.
Applies when
- the site is already built to static files
- readers need to find content by searching, not only by browsing a menu
- the searchable content is known at build time
Client-Side Search for a Static Site
Summary
Build a search index as part of the site build, ship it alongside the static files, and let a small script in the browser query it directly. This pattern is for those who maintain a statically generated site and need real search without reintroducing a server to run it. It reports how the RSE-CEP pattern site does this with Pagefind.
| Recommendation | Why? |
|---|---|
| Generate a compact search index at build time and query it entirely in the browser. | Keeps the runtime a plain file server, so search adds no server to run, patch, or pay for, and the index rebuilds deterministically with the rest of the site. |
| Choose an index format sized to the corpus, and load it lazily. | For larger sites, a whole-corpus index can slow site load; a chunked or lazily fetched index keeps the first paint cheap and scales search to the content that actually exists. |
Context
This pattern extends a statically generated site, so it assumes a build step that already emits static files and content that is known at build time. The genuine prerequisite beyond that is a build-time step that can walk the rendered content and emit an index artefact the browser can fetch.
It does not suit corpora so large that a usable index would exceed what a browser can reasonably download, nor content that needs server-side ranking, per-user access control, or freshness between builds. Where the corpus is large, a hosted search service is the different context and a different pattern.
The pattern also asks the reader to accept client-side JavaScript in the browser, which the strictest, most minimalist readings of the static-site approach will resist on principle. Search is usually a use case potent enough to justify the exception, and the site stays fully browsable without it, so the JavaScript buys a real capability rather than creeping in as decoration.
Usage
Index at build time. Add a step to the build that reads the rendered pages or the structured content and writes a search index into the output directory, so the index ships as just another static file.
Query in the browser. Load a small client script that fetches the index on demand and runs the query locally, so a search never round-trips to a server.
Load the index lazily. Fetch the index on first interaction with the search box rather than on page load, and chunk it where the tooling allows, so search costs nothing until a reader uses it.
Degrade gracefully. Where scripting is unavailable, leave the site fully browsable without search, since the static content is the durable record and search is an enhancement over it.
Implementations
RSE-CEP is the attested implementation. The pattern site is statically generated (see the sibling architectural pattern) and carries a growing corpus of patterns that readers need to search; it builds a search index as a post-build step and queries it entirely in the browser, with no search server in the request path.
The choice worth attesting is the index. RSE-CEP uses Pagefind, which builds a chunked index at build time and fetches only the fragments a query needs. That suited a corpus expected to grow: a chunked index keeps the initial download roughly flat as the pattern count rises, where a single whole-corpus index, the shape Lunr.js builds and a reasonable filler for a smaller fixed site, would grow with it. The accepted tradeoff is that ranking is whatever the client library offers rather than something tunable server-side, and the index is an extra build artefact that rebuilds with the site; both are prices paid gladly to keep the runtime a plain file server.
Client-side search over a static site is unremarkable, heavily attested industry practice, so this is a situated instance rather than a frontier claim. The integration lives in the rse-cep-web repository rather than being reproduced here, since an inlined copy drifts from what actually runs.
References
Models
The approach is the search limb of the Jamstack model: precompute at build time and serve, meeting the dynamic need through a bounded client-side call rather than a server.
Other resources
- Pagefind documents the chunked-index approach for large static sites.
- Lunr.js documents a single-index client-side search suited to smaller sites.
Acknowledgments
This pattern draws on the static-site sustainability concerns raised by participants in the HASS and Indigenous RDC Community Data Lab co-design workshop, who wanted research sites to stay useful without standing up servers.
Principle alignments
- Minimal sustained infrastructure TENET AI-suggested
The pattern's premise is that search requires no server beyond a plain file host: the index is precomputed at build time and queried in the browser. Every recommendation in Summary and Usage reinforces keeping the runtime minimal — lazy loading, chunked indices, graceful degradation all serve the same goal of adding no sustained infrastructure to deliver a dynamic capability.
Reviewed 18 June 2026