Skip to content

Replace DocSearch with a Lunr search dialog - #215

Draft
eric-schneider wants to merge 2 commits into
mainfrom
lunr-search-ui
Draft

eric-schneider wants to merge 2 commits into
mainfrom
lunr-search-ui

Conversation

@eric-schneider

Copy link
Copy Markdown
Contributor

This adds a search dialog that searches the site's own Lunr index in the reader's browser, for sites built with @antora/lunr-extension.

The dialog reuses the existing search dialog's markup and styles, so it looks the same in light and dark mode and on phones. It downloads Lunr and the index only when a reader goes to search, ranks title matches above heading and body matches, groups results by product and version, tolerates typos, and completes the word being typed. It also fixes a Lunr 2.3.9 bug that made some indexed words, such as jvm17, unsearchable.

Sites built without the Lunr extension keep using DocSearch, so releasing this bundle doesn't change the live site until datastax-docs-site's playbooks point at it.

When the site is built with @antora/lunr-extension (which sets
env.SITE_SEARCH_PROVIDER), pages load js/vendor/site-search.js instead
of the DocSearch script. It renders the same markup DocSearch v3 uses,
so the existing DocSearch styles and dark theme apply unchanged, and the
navbar button is rendered in the page HTML (no layout shift while
scripts load).

The script downloads lunr.js and the site's search-index.js only when a
reader shows intent to search (hovering or focusing the button, the
keyboard shortcut, or opening the dialog), then searches locally.
Results are grouped by component and version, with up to three matching
sections under each page. Ranking favors title matches over heading
matches over body text, as DocSearch's does, requires every query word
when some page has them all, tolerates typos, and completes the word
being typed.

The dialog keeps focus and keyboard handling inside itself, closes on
Escape from anywhere and on a plain click of a result, shows an error
(and retries) when the index can't load, scopes and validates recent
searches, and exposes one labeled listbox per result group.

Without the Lunr extension, the Algolia DocSearch integration is used as
before.
lunr.Index.load compresses the index's word list into an automaton by
merging states that have the same key, and Lunr 2.3.9 builds that key by
joining each edge's character and target state id with nothing between
them. When words contain digits, two different states can get the same
key. Some indexed words then can't be found (jvm11, jvm17, 4151 and 4157
in the full site's index), and a few words that aren't in the index are
accepted, which made prefix and typo queries that reached them throw.

Override lunr.TokenSet.prototype.toString to end each edge with a comma
before the index is loaded. With the full site's index, and with one
built from all body text, the automaton then accepts exactly the indexed
words, and "jvm17" finds its 7 HCD pages. guardTokenSet, which only
caught the errors, is removed.
@eric-schneider eric-schneider self-assigned this Oct 12, 2026
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

UI bundle preview build successful! ✅
Deploying bundle preview.
Deploy successful! View preview

@plpesvc-ds

plpesvc-ds commented Oct 12, 2026 •

Copy link
Copy Markdown

Build successful! ✅
Deploying draft.
Deploy successful! View draft

@eric-schneider
eric-schneider marked this pull request as draft October 12, 2026 20:55

This branch has not been deployed

No deployments
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.

2 participants