1
0
Fork 0
docsearch/packages/website/docs/examples.mdx
Dylan Tientcheu 23f3e6b657
refactor(docusaurus-adapter): rework theme config for v5 and modularize SearchPage (#2904)
Co-authored-by: Paul Jankowski <8BitTitan@gmail.com>
2026-07-15 17:24:19 +02:00

358 lines
9.7 KiB
Text

---
id: examples
title: Examples and extensions
description: live demos showing how to use and extend docsearch beyond documentation-only use cases.
---
import { DocSearch } from '@docsearch/react';
import '@docsearch/css/dist/style.css';
> These examples are interactive. click a button to open the modal and try a query.
## Basic keyword search
Use the default experience with your index credentials. this works great for typical docs, blogs, and any site with a docsearch-compliant index.
```jsx
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[{ name: 'docsearch' }]}
insights={true}
translations={{ button: { buttonText: 'keyword search (demo)' } }}
/>
```
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[{ name: 'docsearch' }]}
insights={true}
translations={{ button: { buttonText: 'keyword search (demo)' } }}
/>
---
## Ask AI: ai-assisted answers
Add algolia askai to get synthesized answers grounded in your indexed content. you can scope the llm context using `searchParameters` like `facetFilters`, `filters`, `attributesToRetrieve`,`restrictSearchableAttributes`, and `distinct`.
```jsx
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[{ name: 'docsearch' }]}
askAi={{
assistantId: 'askAIDemo',
}}
insights={true}
translations={{ button: { buttonText: 'search with askai (demo)' } }}
/>
```
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[{ name: 'docsearch' }]}
askAi={{
assistantId: 'askAIDemo',
}}
insights={true}
translations={{ button: { buttonText: 'search with askai (demo)' } }}
/>
---
## Custom hit rendering (`hitComponent`)
Replace the default hit markup to match your brand and layout. below is a minimal example of a custom component.
```jsx
function CustomHit({ hit }) {
// render a compact, branded hit card
return (
<a
href={hit.url}
style={{ display: 'block', padding: '12px 16px', textDecoration: 'none' }}
>
<div style={{ display: 'flex', gap: 12 }}>
<div
style={{
width: 40,
height: 40,
backgroundColor: '#e3f2fd',
borderRadius: 6,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontWeight: 600,
color: '#1976d2',
}}
>
{hit.type?.toUpperCase?.() || 'DOC'}
</div>
<div style={{ minWidth: 0 }}>
<div
style={{
fontWeight: 600,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
{hit.hierarchy?.lvl1 || 'untitled'}
</div>
{hit.hierarchy?.lvl2 && (
<div
style={{
color: '#666',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
{hit.hierarchy.lvl2}
</div>
)}
{hit.content && (
<div style={{ color: '#888', marginTop: 4 }}>{hit.content}</div>
)}
</div>
</div>
</a>
);
}
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[{ name: 'docsearch' }]}
hitComponent={CustomHit}
insights={true}
translations={{ button: { buttonText: 'custom hits (demo)' } }}
/>;
```
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[{ name: 'docsearch' }]}
hitComponent={({ hit }) => {
// render a compact, branded hit card
return (
<a
href={hit.url}
style={{
display: 'block',
padding: '12px 16px',
textDecoration: 'none',
}}
>
<div style={{ display: 'flex', gap: 12 }}>
<div
style={{
width: 40,
height: 40,
backgroundColor: '#e3f2fd',
borderRadius: 6,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontWeight: 600,
color: '#1976d2',
}}
>
{hit.type?.toUpperCase?.() || 'DOC'}
</div>
<div style={{ minWidth: 0 }}>
<div
style={{
fontWeight: 600,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
{hit.hierarchy?.lvl1 || 'untitled'}
</div>
{hit.hierarchy?.lvl2 && (
<div
style={{
color: '#666',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
>
{hit.hierarchy.lvl2}
</div>
)}
{hit.content && (
<div style={{ color: '#888', marginTop: 4 }}>{hit.content}</div>
)}
</div>
</div>
</a>
);
}}
insights={true}
translations={{ button: { buttonText: 'custom hits (demo)' } }}
/>
---
## Opening links in new tabs
By default, DocSearch opens search result links in the current window. If you want results to open in new tabs, you need to use both a custom `hitComponent` and the `navigator` prop to handle both click and keyboard navigation consistently.
```jsx
// Custom hit component with target="_blank"
function HitWithNewTab({ hit, children }) {
return (
<a href={hit.url} target="_blank" rel="noopener noreferrer">
{children}
</a>
);
}
// Navigator configuration to handle keyboard navigation
const newTabNavigator = {
navigate: ({ itemUrl }) => window.open(itemUrl, '_blank'),
navigateNewTab: ({ itemUrl }) => window.open(itemUrl, '_blank'),
navigateNewWindow: ({ itemUrl }) => window.open(itemUrl, '_blank'),
};
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[{ name: 'docsearch' }]}
hitComponent={HitWithNewTab}
navigator={newTabNavigator}
insights={true}
translations={{ button: { buttonText: 'open in new tabs (demo)' } }}
/>;
```
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[{ name: 'docsearch' }]}
hitComponent={({ hit, children }) => (
<a href={hit.url} target="_blank" rel="noopener noreferrer">
{children}
</a>
)}
navigator={{
navigate: ({ itemUrl }) => window.open(itemUrl, '_blank'),
navigateNewTab: ({ itemUrl }) => window.open(itemUrl, '_blank'),
navigateNewWindow: ({ itemUrl }) => window.open(itemUrl, '_blank'),
}}
insights={true}
translations={{ button: { buttonText: 'open in new tabs (demo)' } }}
/>
<br></br>
:::warning
**Note**: Using only `hitComponent` with `target="_blank"` will work for mouse clicks, but keyboard navigation (arrows + Enter) requires the `navigator` prop to consistently open links in new tabs.
:::
---
## Bring-your-own-data shape with `transformItems`
Docsearch is not limited to docsearch-like records. use `transformItems` to adapt any record shape into the internal structure docsearch expects. this lets you build search for apps, help centers, changelogs, or any custom content.
the snippet below maps a non-standard record to the internal format. try it live:
```jsx
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[
{
name: 'crawler_doc',
searchParameters: {
attributesToRetrieve: ['*'],
attributesToSnippet: ['*'],
hitsPerPage: 20,
},
},
]}
askAi={{
assistantId: 'askAIDemo',
}}
transformItems={(items) =>
items.map((item) => ({
objectID: item.objectID,
content: item.content ?? '',
url: item.domain + item.path,
hierarchy: {
lvl0: (item.breadcrumb || []).join(' > ') ?? '',
lvl1: item.h1 ?? '',
lvl2: item.h2 ?? '',
lvl3: null,
lvl4: null,
lvl5: null,
lvl6: null,
},
url_without_anchor: item.domain + item.path,
type: 'content',
anchor: null,
_highlightResult: item._highlightResult,
_snippetResult: item._snippetResult,
}))
}
insights={true}
translations={{ button: { buttonText: 'transform items (demo)' } }}
/>
```
<DocSearch
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
indices={[
{
name: 'crawler_doc',
searchParameters: {
attributesToRetrieve: ['*'],
attributesToSnippet: ['*'],
hitsPerPage: 20,
},
},
]}
askAi={{
assistantId: 'askAIDemo',
}}
transformItems={(items) =>
items.map((item) => ({
objectID: item.objectID,
content: item.content ?? '',
url: item.domain + item.path,
hierarchy: {
lvl0: (item.breadcrumb || []).join(' > ') ?? '',
lvl1: item.h1 ?? '',
lvl2: item.h2 ?? '',
lvl3: null,
lvl4: null,
lvl5: null,
lvl6: null,
},
url_without_anchor: item.domain + item.path,
type: 'content',
anchor: null,
_highlightResult: item._highlightResult,
_snippetResult: item._snippetResult,
}))
}
insights={true}
translations={{ button: { buttonText: 'transform items (demo)' } }}
/>
---
## Tips
- **Instrumentation**: enable `insights` to send usage analytics and iterate on relevance.
- **Ask AI scoping**: use `facetFilters`, `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct` to control ai context and improve answer quality.
- **Customization**: use `hitComponent`, `transformItems`, and `translations` to make docsearch feel native to any product surface.