Add a page search to the top of the left menu - #1024
Merged
Conversation
Closes #970. The Hextra theme's search went away with Hugo, and with it the only way to find a test specification by name: the board's existing search box filters framework rows, so a query like "prior-knowledge" or "MTU" matched nothing anywhere on the site. 124 Knowledge Base pages were reachable only by walking the tree. Search covers the Knowledge Base by title AND full body text, plus every leaderboard destination (28 profile views and the 6 composite scopes), so "h2c" reaches both the JSON (h2c) board and its implementation page. Results are ranked: a title hit outranks a body hit, an exact title match wins outright, and views float slightly above docs since they are the cheaper landing. Multi-word queries are AND (every term must appear somewhere), each doc hit carries a breadcrumb and a snippet with the match highlighted, and the list caps at 25. No dependency and no index file. docs.js already ships every page's rendered HTML, so the index is built from what is already in memory, on the first keystroke rather than at load -- 158 entries over 0.24 MB of text in ~5 ms. Tags are stripped with a regex rather than by assigning to a detached innerHTML, because that would fetch any <img> the docs grow later. Two structural details: buildNav() now clears #navTree instead of #nav. The search box is static markup above it, so it survives the nav rebuild that every navigation triggers -- otherwise typing would lose focus as soon as results changed. On mobile the tree is still hidden in favour of the existing select, but .nav is no longer display:none, so the search bar itself stays reachable. Keyboard: arrows move the selection, Enter opens, Escape clears. Opening a result clears the query first, so the user lands on a normal menu showing where they now are. Colours come from the existing theme variables, so light and dark both work. Verified end-to-end in headless Chrome against the real data files: the tree builds into its new container, typing "fortunes" yields 6 hits with the tree hidden and the first hit selected, ArrowDown moves the selection, clicking a docs hit renders the page and rewrites the URL to #doc=test-profiles/h1/isolated/fortunes (so results stay deep-linkable), the input clears and the tree comes back, a nonsense query shows the empty state, and Escape restores everything. Checked at 1400px and 400px.
MDA2AV
added a commit
to Kaliumhexacyanoferrat/HttpArena
that referenced
this pull request
Jul 24, 2026
Resolves the conflict GitHub reported against this PR. Nothing conflicted textually: the PR renames site/static/new-leaderboard/index.html to site/leaderboard/index.html while main modified it in place, and GitHub's mergeability check does not apply rename detection, so it reported the pair as a modify/delete conflict. `git merge-tree --write-tree` exits 0 and both merge directions are clean locally. Carries in the three changes main made to that file since this branch forked at 6bcf729: MDA2AV#1024 the Knowledge Base page search in the left menu (#navq, #navTree, buildSearchIndex) — note buildNav() now clears #navTree, not #nav MDA2AV#1025 the .tsq-* type square colours, which MDA2AV#1017 had deleted by way of a shared CSS line MDA2AV#1018 the type-rules "standard" attribute rename in the generator all of which land in the renamed file and the renamed generator.
MDA2AV
added a commit
to Kaliumhexacyanoferrat/HttpArena
that referenced
this pull request
Jul 24, 2026
Three things, all in service of this PR's goal of making the docs indexable.
1. Authored title + description for all 123 pages
The generator derived the meta description from each page's first <p>. That
opening line is often a cross-reference ("Same workload as JSON Processing,
but…"), which reads as boilerplate in a search result. Descriptions are now
authored in frontmatter; the scrape stays as the fallback for any page that
lacks one.
Titles were worse: 123 pages shared only 71 distinct titles, because 26 are
called "Implementation Guidelines" and 26 more "Validation". As <title> tags
those compete with each other for the same query, and a result reading just
"Validation" says nothing about which test it covers. A new `seo_title`
frontmatter key overrides the tag without touching the sidebar label, so
navigation still reads "Validation" while the page is titled "Baseline
Throughput Benchmark — Validation Checks".
Result: 123 unique titles, 123 unique descriptions, 81-153 characters each.
The SPA index page's own title and description are untouched.
2. The board's page search had been left indexing nothing
MDA2AV#1024 added Knowledge Base search to the left menu, built from window.LB_DOCS
— the docs.js blob. This PR stops generating docs.js, so LB_DOCS is always {}
and the search silently degraded to the 34 leaderboard views: no
documentation results at all, which is the exact complaint MDA2AV#970 was opened
about.
Reverting to docs.js would undo the payload win, so the generator now emits
search.js instead: the same pages as plain text, prepared server-side. It is
266 KB against docs.js's 427 KB, needs no client-side tag stripping, and each
entry carries the URL of its real page, so a hit navigates to /docs/<id>/
rather than rendering in place. The authored description is indexed too.
stripHtml() and docCrumb() go with it — both existed only to process the
retired HTML blob.
3. deploy.yml ships search.js alongside data.js.
Verified by regenerating: 123 static pages, 123 unique titles and
descriptions with no page over 160 characters, a 123-entry search index, and
a 124-URL sitemap.
MDA2AV
added a commit
that referenced
this pull request
Jul 24, 2026
* Remove old leaderboar and optimize SEO
* Add per-page SEO metadata, and keep the board's page search working
Three things, all in service of this PR's goal of making the docs indexable.
1. Authored title + description for all 123 pages
The generator derived the meta description from each page's first <p>. That
opening line is often a cross-reference ("Same workload as JSON Processing,
but…"), which reads as boilerplate in a search result. Descriptions are now
authored in frontmatter; the scrape stays as the fallback for any page that
lacks one.
Titles were worse: 123 pages shared only 71 distinct titles, because 26 are
called "Implementation Guidelines" and 26 more "Validation". As <title> tags
those compete with each other for the same query, and a result reading just
"Validation" says nothing about which test it covers. A new `seo_title`
frontmatter key overrides the tag without touching the sidebar label, so
navigation still reads "Validation" while the page is titled "Baseline
Throughput Benchmark — Validation Checks".
Result: 123 unique titles, 123 unique descriptions, 81-153 characters each.
The SPA index page's own title and description are untouched.
2. The board's page search had been left indexing nothing
#1024 added Knowledge Base search to the left menu, built from window.LB_DOCS
— the docs.js blob. This PR stops generating docs.js, so LB_DOCS is always {}
and the search silently degraded to the 34 leaderboard views: no
documentation results at all, which is the exact complaint #970 was opened
about.
Reverting to docs.js would undo the payload win, so the generator now emits
search.js instead: the same pages as plain text, prepared server-side. It is
266 KB against docs.js's 427 KB, needs no client-side tag stripping, and each
entry carries the URL of its real page, so a hit navigates to /docs/<id>/
rather than rendering in place. The authored description is indexed too.
stripHtml() and docCrumb() go with it — both existed only to process the
retired HTML blob.
3. deploy.yml ships search.js alongside data.js.
Verified by regenerating: 123 static pages, 123 unique titles and
descriptions with no page over 160 characters, a 123-entry search index, and
a 124-URL sitemap.
---------
Co-authored-by: MDA2AV <fabreis202@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #970. The Hextra theme's search went away with Hugo, and with it the only way to find a test specification by name: the board's existing search box filters framework rows, so a query like "prior-knowledge" or "MTU" matched nothing anywhere on the site. 124 Knowledge Base pages were reachable only by walking the tree.
Search covers the Knowledge Base by title AND full body text, plus every leaderboard destination (28 profile views and the 6 composite scopes), so "h2c" reaches both the JSON (h2c) board and its implementation page.
Results are ranked: a title hit outranks a body hit, an exact title match wins outright, and views float slightly above docs since they are the cheaper landing. Multi-word queries are AND (every term must appear somewhere), each doc hit carries a breadcrumb and a snippet with the match highlighted, and the list caps at 25.
No dependency and no index file. docs.js already ships every page's rendered HTML, so the index is built from what is already in memory, on the first keystroke rather than at load -- 158 entries over 0.24 MB of text in ~5 ms. Tags are stripped with a regex rather than by assigning to a detached innerHTML, because that would fetch any
the docs grow later.
Two structural details:
buildNav() now clears #navTree instead of #nav. The search box is static markup above it, so it survives the nav rebuild that every navigation triggers -- otherwise typing would lose focus as soon as results changed.
On mobile the tree is still hidden in favour of the existing select, but .nav is no longer display:none, so the search bar itself stays reachable.
Keyboard: arrows move the selection, Enter opens, Escape clears. Opening a result clears the query first, so the user lands on a normal menu showing where they now are. Colours come from the existing theme variables, so light and dark both work.
Verified end-to-end in headless Chrome against the real data files: the tree builds into its new container, typing "fortunes" yields 6 hits with the tree hidden and the first hit selected, ArrowDown moves the selection, clicking a docs hit renders the page and rewrites the URL to #doc=test-profiles/h1/isolated/fortunes (so results stay deep-linkable), the input clears and the tree comes back, a nonsense query shows the empty state, and Escape restores everything. Checked at 1400px and 400px.
Description
PR Commands — comment on this PR to trigger (requires collaborator approval):
/benchmark -f <framework>/benchmark -f <framework> -t <test>/benchmark -f <framework> --saveAlways specify
-f <framework>. Results are automatically compared against the current leaderboard.Run benchmarks locally
You can validate and benchmark your framework locally with the lite script — no CPU pinning, fixed connection counts, all load generators run in Docker.
Requirements: Docker Engine on Linux. Load generators (gcannon, h2load, h2load-h3, wrk, ghz) are built as self-contained Docker images on first run.