Skip to content

Commit 33ddb41

Browse files
committed
Fix search threshold
1 parent a7c92a8 commit 33ddb41

10 files changed

Lines changed: 24579 additions & 19 deletions

File tree

_TODO.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,6 @@ The bigger problem on this homepage is still total shipped JS and chunk fan-out,
321321

322322
If you want, I can next turn that into a plain-English takeaway for your _TODO.md, like: "fan-out is the main issue; dependency waterfall is present but shallow."
323323

324-
### Search page
325-
326-
One route that is dynamic now but probably does not need to be:
327-
328-
/search
329-
330-
It is currently marked prerender = false in index.astro:2, but the UI is already client-driven. index.astro:8 reads q, and the real search happens through the action in action.ts:12. That means /search can very likely be a static shell page and let the client read window.location.search and call the action. So I would not keep this dynamic unless you specifically want SSR-rendered search results for SEO.
331-
332324
### Tags page
333325

334326
One caution:
@@ -341,7 +333,6 @@ In src/pages/tags/[tag].astro, the route sets ITEMS_PER_PAGE = 12, then reads th
341333

342334
src/pages/tags/[tag].astro
343335

344-
345336
const currentPage = parseInt(Astro.url.searchParams.get('page') || '1')
346337
It uses that value to:
347338

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"lint:actions": "FORCE_COLOR=1 npx node-actionlint && FORCE_COLOR=1 python3 -m pylint $(find .github/actions -type f -path '*/src/*.py')",
5353
"lint:code": "npx eslint \"@types/**/*.{js,ts}\" \"src/**/*.{js,ts,tsx,astro}\" \"test/**/*.{js,ts,tsx,astro}\"",
5454
"lint:inclusive-language": "npx alex src/content",
55-
"lint:json": "FORCE_COLOR=1 npx prettier \"**/*.json\" --cache --check --ignore-path .gitignore --ignore-path .prettierignore",
55+
"lint:json": "FORCE_COLOR=1 npx prettier \"**/*.json\" '!**/www.*.json' --cache --check --ignore-path .gitignore --ignore-path .prettierignore",
5656
"lint:md": "FORCE_COLOR=1 npx markdownlint-cli2 \"**/*.{md,mdx}\" \"!**/node_modules/**\" \"!**/dist/**\" \"!**/.astro/**\" \"!**/dev-dist/**\" \"!**/__blobstorage__/**\"",
5757
"lint:style": "FORCE_COLOR=1 npx stylelint \"src/**/*.{css,astro}\"",
5858
"lint:tsc:check": "npm run sync && tsc --noEmit -p tsconfig.json --pretty false",

src/actions/search/__tests__/responder.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ describe('mapUpstashSearchResults', () => {
5151
const raw = [
5252
{
5353
id: 'doc-1',
54-
score: 0.39,
54+
score: 0.009,
5555
content: {
5656
url: '/articles/low-score',
5757
title: 'Low Score',
@@ -60,7 +60,7 @@ describe('mapUpstashSearchResults', () => {
6060
},
6161
{
6262
id: 'doc-2',
63-
score: 0.4,
63+
score: 0.01,
6464
content: {
6565
url: '/articles/high-enough',
6666
title: 'High Enough',
@@ -73,7 +73,7 @@ describe('mapUpstashSearchResults', () => {
7373

7474
expect(hits).toHaveLength(1)
7575
expect(hits[0]?.title).toBe('High Enough')
76-
expect(hits[0]?.score).toBe(0.4)
76+
expect(hits[0]?.score).toBe(0.01)
7777
})
7878

7979
it('deduplicates hits that resolve to the same canonical path', () => {

src/actions/search/responder.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import type { DefaultSearchResult, SearchHit } from '@actions/search/@types'
22

3-
const MIN_RELEVANCY_SCORE = 0.4
3+
// Upstash reranking now returns normalized scores where strong matches commonly
4+
// land well below 0.4. Keep a small floor to drop near-zero noise while still
5+
// surfacing legitimate results.
6+
const MIN_RELEVANCY_SCORE = 0.01
47

58
const getCanonicalResultPath = (url: string): string => {
69
try {

src/components/Search/SearchResults/client/__tests__/index.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,29 @@ describe('SearchResults web component', () => {
296296
}
297297
)
298298
})
299+
300+
it('seeds the initial query from the location when the rendered input starts empty', async () => {
301+
searchQueryMock.mockResolvedValue({
302+
data: {
303+
hits: [
304+
{
305+
title: 'Astro Search',
306+
url: '/articles/astro-search',
307+
snippet: '...',
308+
},
309+
],
310+
},
311+
})
312+
313+
await runComponentRender({ query: '' }, async ({ element, window }) => {
314+
window.history.replaceState(window.history.state, '', '/search?q=astro')
315+
316+
await (element as unknown as { run: () => Promise<void> }).run()
317+
await flushMicrotasks()
318+
319+
const input = element.querySelector('[data-search-input]') as HTMLInputElement | null
320+
expect(input?.value).toBe('astro')
321+
expect(searchQueryMock).toHaveBeenCalledWith({ q: 'astro', limit: 20 })
322+
})
323+
})
299324
})

src/components/Search/SearchResults/client/index.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,31 @@ export class SearchResultsElement extends LitElement {
106106
this.micBtn = micBtn
107107
this.clearBtn = clearBtn
108108

109+
this.syncInitialQueryState()
109110
this.updateClearButtonVisibility()
110111
this.updateMicButtonVisibility()
111112
}
112113

114+
private getInitialQuerySeed(): string {
115+
return (this.query ?? '').trim() || this.getQueryFromLocation()
116+
}
117+
118+
private syncInitialQueryState(): void {
119+
const initialQuery = this.getInitialQuerySeed()
120+
121+
if (!initialQuery) {
122+
return
123+
}
124+
125+
if (!this.query?.trim()) {
126+
this.query = initialQuery
127+
}
128+
129+
if (this.input && this.input.value.trim().length === 0) {
130+
this.input.value = initialQuery
131+
}
132+
}
133+
113134
private attachListeners(): void {
114135
if (!this.input || !this.form || !this.micBtn || !this.clearBtn) {
115136
return
@@ -509,8 +530,18 @@ export class SearchResultsElement extends LitElement {
509530
this.startSpeechRecognition()
510531
}
511532

512-
private async run(queryOverride?: string): Promise<void> {
533+
private resolveRunQuery(queryOverride?: string): string {
513534
const query = (queryOverride ?? this.getQuery()).trim()
535+
536+
if (query.length > 0 || typeof queryOverride === 'string') {
537+
return query
538+
}
539+
540+
return this.getInitialQuerySeed()
541+
}
542+
543+
private async run(queryOverride?: string): Promise<void> {
544+
const query = this.resolveRunQuery(queryOverride)
514545
this.query = query
515546
this.clearError()
516547
this.replaceLocationQuery(query)

src/pages/search/index.astro

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
---
2-
export const prerender = false
2+
export const prerender = true
33
44
import PageLayout from '@layouts/PageLayout.astro'
55
import SearchResults from '@components/Search/SearchResults/index.astro'
66
7-
const query = (Astro.url.searchParams.get('q') ?? '').trim()
8-
97
const pageTitle = 'Search'
108
const pageDescription = 'Search the Site'
119
const path = '/search'
@@ -19,6 +17,6 @@ const path = '/search'
1917
path={path}
2018
>
2119
<div class="max-w-4xl mx-auto">
22-
<SearchResults query={query} />
20+
<SearchResults />
2321
</div>
2422
</PageLayout>

test/unit/helpers/litRuntime.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ export const renderInJsdom = async <TModule extends WebComponentModule>(
216216
const { container, component, args, moduleLoader, selector, waitForReady = defaultWaitForReady, assert } = _options
217217

218218
await withJsdomEnvironment(async ({ window }) => {
219+
window.history.replaceState(window.history.state, '', 'http://localhost/')
220+
219221
const module = await moduleLoader()
220222
await module.registerWebComponent(module.registeredName)
221223

www.webstackbuilders.com-home-desktop-20260423T190519.json

Lines changed: 12244 additions & 0 deletions
Large diffs are not rendered by default.

www.webstackbuilders.com-home-mobile-20260423T184028.json

Lines changed: 12266 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)