Skip to content

Replace site search with Pagefind - #2096

Open
haranrk wants to merge 1 commit into
google:mainfrom
haranrk:search/pagefind
Open

Replace site search with Pagefind#2096
haranrk wants to merge 1 commit into
google:mainfrom
haranrk:search/pagefind

Conversation

@haranrk

@haranrk haranrk commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces MkDocs Material's lunr search with Pagefind 1.5.2.

Three problems with search today: ranking surfaces the wrong page, several hits from one page appear as unrelated entries, and the header dropdown caps what you can see. This fixes all three and drops the multi-megabyte search_index.json every visitor downloads up front.

Pagefind ships a Python wheel, so the build stays pip-only and CI is unchanged.

Screenshots

Searching LlmAgent. One card per page, with the matching headings nested beneath it, and the whole result set scrolls.

Search modal showing results for LlmAgent, grouped by page

Dark mode The same search results with the dark palette applied

The ranking playground, written only under MKDOCS_PAGEFIND_PLAYGROUND=1. It scores the LLM agents page above workflow patterns at the termSimilarity: 2.0 this PR ships.

Pagefind playground showing 226 indexed pages, ranking sliders and scored results

What changed

  • hooks/pagefind.py (new) marks each page's indexable region, runs the indexer in on_post_build, and fails the build if the output is wrong.
  • mkdocs.yml drops the search plugin and registers the hook.
  • overrides/ swaps Material's search button for Pagefind's modal, sets ranking, and mirrors dark mode.
  • docs/stylesheets/custom.css removes dead .md-search rules and adds --pf-* theming.
  • requirements.txt pins pagefind[bin]==1.5.2.

Indexing reads built HTML, so it needs no knowledge of markdown, macros, or redirects, and behaves the same under build, serve, --dirty, Netlify previews, and gh-deploy.

Scope

226 handwritten pages. The generated API reference under docs/api-reference/ stays unindexed, as it is today. Any page can opt out with search: exclude: true front matter.

Verified in a browser

  • 11 of 11 checklist queries return the expected page. LlmAgent returns the LLM agents page; with default ranking it returns workflow patterns, so the one tuned parameter (termSimilarity: 2.0) is doing real work.
  • Results group as one card per page, with matching headings beneath deep-linking to their anchors.
  • The result list scrolls, checked from 360px to 1280px.
  • First search fetches roughly 240 KB of lazily chunked index.

Cmd/Ctrl+K, /, or s opens search.

Build guards

The failure worth preventing is a green build shipping dead search, so six conditions abort the build. Each was verified by deliberately breaking it.

  1. The content <article> anchor stopped matching, after a theme change.
  2. No page was marked for indexing.
  3. Indexed page count does not equal marked page count.
  4. The search UI assets were not emitted.
  5. A class in --exclude-selectors no longer appears in any indexed page, which is how fused tokens would silently return.
  6. The JavaScript ranking API is missing from the bundle.

gh-deploy additionally refuses to publish if indexing was skipped.

Known tradeoffs

  • memory, a2a, bigquery, and callbacks return a deeper page rather than the section overview.
  • Material's ?h= arrival highlighting is gone. Pagefind's equivalent costs 44 KB on every page load, and results already land on the matching heading.
  • Build time grows about 2 seconds. MKDOCS_PAGEFIND_SKIP=1 is the local escape hatch, and is deliberately ineffective on the paths that ship.

@netlify

netlify Bot commented Aug 8, 2026

Copy link
Copy Markdown

Deploy Preview for adk-docs-preview ready!

Name Link
🔨 Latest commit df24634
🔍 Latest deploy log https://app.netlify.com/projects/adk-docs-preview/deploys/6a7a5fcc73af670008213966
😎 Deploy Preview https://deploy-preview-2096--adk-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Material's search ranked identifier queries badly, split one page across
a row per heading, and showed only the first handful of matches. Pagefind
indexes at build time, groups sub-results under their page, and pages
through the whole result set.

hooks/pagefind.py marks each page's content <article> with
data-pagefind-body and runs the indexer over the built site. It fails the
build on six conditions: the anchor missing, nothing marked, marked and
indexed counts disagreeing, an exclude selector matching no page, a UI
asset not emitted, and the ranking API gone from the bundle.
MKDOCS_PAGEFIND_SKIP=1 skips indexing for a faster `mkdocs serve`, warns
so that --strict fails pull requests, and is refused under gh-deploy,
which publishes without --strict.

The header hosts Pagefind's own modal and trigger components, so there is
little UI to own. overrides/main.html raises termSimilarity so "LlmAgent"
beats pages that merely say "agent" often, mirrors Material's colour
scheme onto data-pf-theme, clears the search input on close around an
upstream bug, and restores the / and s shortcuts that left with the old
plugin. The lunr-specific CSS is gone.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant