Skip to content

Commit 26c99e4

Browse files
estradinoclaude
andauthored
search: purge stale Algolia records on deploy, fix EN result URLs, polish dropdown (#275)
1. Stale duplicates — index-to-algolia.cjs used saveObjects(), which only adds/updates and never deletes, so records from old slug formats (e.g. the pre-language-prefix EN slugs) lingered across deploys. Switch to replaceAllObjects(... { safe: true }) so each deploy atomically replaces the whole index and drops pages/slugs that no longer exist. 2. Broken EN result links — the index stores EN slugs with an `en/` prefix, but production/preview serve the default locale at the site root (/installation/…), so EN hits linked to /en/… and 404'd. DocSearch transformItems now strips the leading /en off result URLs on non-localhost hosts (localhost still serves /en/). 3. Visual — theme the DocSearch modal/results/recents/footer with the redesign tokens (Figtree, 16px modal radius, soft surface-2 input with accent focus ring, accent section headers, accent-soft selected row, kbd-styled footer keys). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent dc6749b commit 26c99e4

3 files changed

Lines changed: 53 additions & 9 deletions

File tree

scripts/index-to-algolia.cjs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,20 @@ readFile(__dirname + '/../public/search-index.json', (err, data) => {
3030
body: page.body
3131
})
3232
})
33-
const chunkSize = 500;
34-
for (let i = 0; i < objects.length; i += chunkSize) {
35-
const chunk = objects.slice(i, i + chunkSize);
36-
// do wher
37-
index.saveObjects(chunk)
33+
// replaceAllObjects atomically replaces the ENTIRE index with the current
34+
// build's objects (temp index + atomic move, batching handled internally).
35+
// Records for pages that no longer exist — e.g. old slug formats left over
36+
// from earlier deploys — are dropped instead of lingering forever.
37+
// saveObjects() only added/updated and never deleted, which is what left
38+
// stale duplicates in the index.
39+
index.replaceAllObjects(objects, { safe: true })
3840
.then( ({objectIDs}) => {
39-
console.log(objectIDs.length, " elements indexed")
41+
console.log(objectIDs.length, " elements indexed (index fully replaced)")
42+
console.log("Process done")
4043
}).catch( err => {
4144
console.log(err)
4245
console.log(err.transporterStackTrace)
4346
})
44-
}
45-
console.log("Process done")
4647
} catch (e) {
4748
console.error("Error parsing index JSON data")
4849
console.error(e)

src/components/Header/DocSearch.css

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,38 @@
112112

113113

114114
}
115+
116+
/* ============================================================
117+
Redesign polish for the search dropdown (results, recents, footer)
118+
============================================================ */
119+
.DocSearch-Modal { font-family: var(--fb); border-radius: 16px; }
120+
121+
/* section / group headers (e.g. "Sanitize Data (Web)", "Recent") */
122+
.DocSearch-Hit-source {
123+
font-family: var(--fb);
124+
font-weight: 700;
125+
font-size: 12px;
126+
letter-spacing: 0.02em;
127+
color: var(--accent);
128+
padding-top: 14px;
129+
}
130+
131+
/* result + recent rows */
132+
.DocSearch-Hit a { background: transparent; }
133+
.DocSearch-Hit[aria-selected='true'] a { background: var(--accent-soft); }
134+
.DocSearch-Hit-title { color: var(--text-2); }
135+
.DocSearch-Hit-icon, .DocSearch-Hit-Tree { color: var(--text-3); }
136+
137+
/* favourite (star) + remove (x) buttons on recents */
138+
.DocSearch-Hit-action { color: var(--text-3); }
139+
.DocSearch-Hit-action:hover { color: var(--accent); }
140+
141+
/* footer key-hints → redesign kbd look */
142+
.DocSearch-Footer { background: var(--surface); }
143+
.DocSearch-Commands-Key {
144+
border-radius: 6px;
145+
background: var(--surface-2);
146+
box-shadow: inset 0 -1px 0 var(--or-border);
147+
color: var(--text-3);
148+
}
149+
.DocSearch-Label, .DocSearch-Commands li { color: var(--text-3); font-family: var(--fb); }

src/components/Header/DocSearch.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ export default function Search({ lang = 'en', labels }: Props) {
6666
// searchParameters={{ facetFilters: [`lang:${lang}`, `version:${version}`] }}
6767
// hitComponent={CustomHit}
6868
transformItems={(items) => {
69+
// Production/preview builds serve the default locale (en) at the site
70+
// root (e.g. /installation/...), so a slug like "en/installation/x"
71+
// must drop its /en prefix or the result 404s. On localhost pages are
72+
// served under /en/, so keep it there.
73+
const onLocalhost =
74+
typeof location !== 'undefined' &&
75+
(location.hostname === 'localhost' || location.hostname.startsWith('127.'));
6976
return items.map((item) => {
7077
// We transform the absolute URL into a relative URL to
7178
// work better on localhost, preview URLS.
@@ -74,9 +81,10 @@ export default function Search({ lang = 'en', labels }: Props) {
7481
item.type = 'lvl1';
7582
item.title = '';
7683
const hash = a.hash === '#overview' ? '' : a.hash;
84+
const pathname = onLocalhost ? a.pathname : a.pathname.replace(/^\/en(?=\/|$)/, '');
7785
return {
7886
...item,
79-
url: `${a.pathname}${hash}`,
87+
url: `${pathname || '/'}${hash}`,
8088
};
8189
});
8290
}}

0 commit comments

Comments
 (0)