Skip to content

Commit 2996410

Browse files
authored
Improve docs search results and experience (#2866)
* feat(docs): enhance search system with improved indexing Signed-off-by: Mislav Ivanda <[email protected]> * feat(docs): add CLI/SDK search indices, no search results handling update Signed-off-by: Mislav Ivanda <[email protected]> * style: formatting improvements and fix switch fallthrough Signed-off-by: Mislav Ivanda <[email protected]> --------- Signed-off-by: Mislav Ivanda <[email protected]>
1 parent c7a45a8 commit 2996410

File tree

2 files changed

+202
-52
lines changed

2 files changed

+202
-52
lines changed

apps/docs/src/components/Search.jsx

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import '../styles/components/search.scss'
1818

1919
const ALGOLIA_APP_ID = import.meta.env.PUBLIC_ALGOLIA_APP_ID || null
2020
const ALGOLIA_API_KEY = import.meta.env.PUBLIC_ALGOLIA_API_KEY || null
21+
const DOCS_INDEX_NAME =
22+
import.meta.env.PUBLIC_ALGOLIA_DOCS_INDEX_NAME || 'docs_test'
23+
const CLI_INDEX_NAME = import.meta.env.PUBLIC_ALGOLIA_CLI_INDEX_NAME || 'cli_test'
24+
const SDK_INDEX_NAME = import.meta.env.PUBLIC_ALGOLIA_SDK_INDEX_NAME || 'sdk_test'
2125

2226
const searchClient =
2327
ALGOLIA_APP_ID && ALGOLIA_API_KEY
@@ -29,6 +33,7 @@ function SearchContent() {
2933
const [searchQuery, setSearchQuery] = useState('')
3034
const [debounceQuery, setDebounceQuery] = useState('')
3135
const [displayHits, setDisplayHits] = useState(false)
36+
const [totalHits, setTotalHits] = useState(0)
3237
const debounceTimeoutRef = useRef(null)
3338
const searchWrapperRef = useRef(null)
3439
const t = useGT()
@@ -40,6 +45,7 @@ function SearchContent() {
4045
setSearchQuery('')
4146
setDebounceQuery('')
4247
setDisplayHits(false)
48+
setTotalHits(0)
4349
}
4450
return !prev
4551
})
@@ -54,6 +60,7 @@ function SearchContent() {
5460
setSearchQuery('')
5561
setDebounceQuery('')
5662
setDisplayHits(false)
63+
setTotalHits(0)
5764
}
5865
}
5966

@@ -75,6 +82,7 @@ function SearchContent() {
7582
setSearchQuery('')
7683
setDebounceQuery('')
7784
setDisplayHits(false)
85+
setTotalHits(0)
7886
}
7987
}
8088

@@ -103,6 +111,7 @@ function SearchContent() {
103111
}
104112

105113
debounceTimeoutRef.current = setTimeout(() => {
114+
setTotalHits(0)
106115
setDebounceQuery(searchQuery)
107116
}, 400)
108117

@@ -120,7 +129,7 @@ function SearchContent() {
120129
className="searchbox-wrapper"
121130
ref={searchWrapperRef}
122131
>
123-
<InstantSearch indexName="docs" searchClient={searchClient}>
132+
<InstantSearch indexName={DOCS_INDEX_NAME} searchClient={searchClient}>
124133
<div className="search-bar-container">
125134
<SearchBox
126135
translations={{
@@ -137,22 +146,36 @@ function SearchContent() {
137146
{debounceQuery && (
138147
<>
139148
<SearchIndex
140-
indexName="docs"
149+
indexName={DOCS_INDEX_NAME}
141150
setDisplayHits={setDisplayHits}
142151
setIsSearchVisible={setIsSearchVisible}
152+
setTotalHits={setTotalHits}
153+
debounceQuery={debounceQuery}
143154
/>
144-
<hr style={{ marginBottom: '40px' }} />
145155
<SearchIndex
146-
indexName="blogs_test"
156+
indexName={CLI_INDEX_NAME}
147157
setDisplayHits={setDisplayHits}
148158
setIsSearchVisible={setIsSearchVisible}
159+
setTotalHits={setTotalHits}
160+
debounceQuery={debounceQuery}
149161
/>
150-
<hr style={{ marginBottom: '40px' }} />
151162
<SearchIndex
152-
indexName="website"
163+
indexName={SDK_INDEX_NAME}
153164
setDisplayHits={setDisplayHits}
154165
setIsSearchVisible={setIsSearchVisible}
166+
setTotalHits={setTotalHits}
167+
debounceQuery={debounceQuery}
155168
/>
169+
{totalHits === 0 && (
170+
<div style={{
171+
textAlign: 'center',
172+
padding: '20px',
173+
color: 'var(--primary-text-color)',
174+
fontSize: '16px'
175+
}}>
176+
No results found for "<strong>{debounceQuery}</strong>"
177+
</div>
178+
)}
156179
</>
157180
)}
158181
<Configure hitsPerPage={10} clickAnalytics getRankingInfo={false} />
@@ -163,9 +186,32 @@ function SearchContent() {
163186
)
164187
}
165188

166-
function SearchIndex({ indexName, setDisplayHits, setIsSearchVisible }) {
189+
function SearchIndex({ indexName, setDisplayHits, setIsSearchVisible, setTotalHits, debounceQuery }) {
167190
return (
168191
<Index indexName={indexName}>
192+
<ConditionalSearchIndex
193+
indexName={indexName}
194+
setDisplayHits={setDisplayHits}
195+
setIsSearchVisible={setIsSearchVisible}
196+
setTotalHits={setTotalHits}
197+
debounceQuery={debounceQuery}
198+
/>
199+
</Index>
200+
)
201+
}
202+
203+
const ConditionalSearchIndexComponent = ({ indexName, setDisplayHits, setIsSearchVisible, nbHits, setTotalHits, debounceQuery }) => {
204+
useEffect(() => {
205+
setDisplayHits(nbHits > 0)
206+
setTotalHits(prev => prev + nbHits)
207+
}, [nbHits, setDisplayHits, setTotalHits, debounceQuery])
208+
209+
if (nbHits === 0) {
210+
return null
211+
}
212+
213+
return (
214+
<>
169215
<div data-index={indexName}>
170216
<div
171217
className="stats-pagination-wrapper"
@@ -190,10 +236,13 @@ function SearchIndex({ indexName, setDisplayHits, setIsSearchVisible }) {
190236
)}
191237
/>
192238
</div>
193-
</Index>
239+
<hr style={{ marginBottom: '40px' }} />
240+
</>
194241
)
195242
}
196243

244+
const ConditionalSearchIndex = connectStats(ConditionalSearchIndexComponent)
245+
197246
function Hit({ hit, setIsSearchVisible, indexName }) {
198247
const handleClick = e => {
199248
e.preventDefault()
@@ -206,7 +255,7 @@ function Hit({ hit, setIsSearchVisible, indexName }) {
206255
}
207256

208257
const currentUrl = window.location.href
209-
258+
210259
if (currentUrl.includes(hitUrl)) {
211260
const element = document.querySelector(`[data-slug='${hit.slug}']`)
212261
if (element) {
@@ -228,7 +277,7 @@ function Hit({ hit, setIsSearchVisible, indexName }) {
228277
}}
229278
>
230279
<a href={hit.url} tabIndex="-1" onClick={handleClick}>
231-
{(indexName === 'docs' || indexName === 'website') && (
280+
{([DOCS_INDEX_NAME, CLI_INDEX_NAME, SDK_INDEX_NAME].includes(indexName) || indexName === 'website') && (
232281
<>
233282
<h5
234283
style={{
@@ -310,12 +359,16 @@ const CustomStats = ({ nbHits, indexName, setDisplayHits }) => {
310359

311360
const getIndexLabel = () => {
312361
switch (indexName) {
313-
case 'docs':
362+
case DOCS_INDEX_NAME:
314363
return 'Documentation'
315364
case 'blogs_test':
316365
return 'Blog'
317366
case 'website':
318367
return 'Website'
368+
case CLI_INDEX_NAME:
369+
return 'CLI'
370+
case SDK_INDEX_NAME:
371+
return 'SDK'
319372
default:
320373
return 'Results'
321374
}

0 commit comments

Comments
 (0)