Technical Documentation: algolia/docsearch
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (README.md)
DocSearch crawls your documentation, pushes the content to an Algolia index and provides a dropdown search experience on your website.
Preview
Usage
Don't have your Algolia credentials yet? Apply to DocSearch!
JavaScript
Installation
bun add @docsearch/js@5
# or
npm install @docsearch/js@5If you don’t want to use a package manager, you can use a standalone endpoint:
<script src="https://cdn.jsdelivr.net/npm/@docsearch/js@5"></script>Get started
To get started, you need a container for your DocSearch component to go in. If you don’t have one already, you can insert one into your markup:
<div id="docsearch"></div>Then, insert DocSearch into it by calling the docsearch function and providing the container. It can be a CSS selector or an Element.
Make sure to provide a container (for example, a div), not an input. DocSearch generates a fully accessible search box for you.
import docsearch from '@docsearch/js';
import '@docsearch/css';
docsearch({
container: '#docsearch',
appId: 'YOUR_APP_ID',
indices: ['YOUR_INDEX_NAME'],
apiKey: 'YOUR_SEARCH_API_KEY',
});React
Installation
bun add @docsearch/react@5
# or
npm install @docsearch/react@5If you don’t want to use a package manager, you can use a standalone endpoint:
<script src="https://cdn.jsdelivr.net/npm/@docsearch/react@5"></script>Get started
DocSearch generates a fully accessible search box for you.
import { DocSearch } from '@docsearch/react';
import '@docsearch/css';
function App() {
return (
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices=["YOUR_ALGOLIA_INDEX"]
/>
);
}
export default App;Styling
MCP plugins
Client plugins for the public DocSearch MCP endpoint are in mcp/plugins/docsearch. They connect ChatGPT, Codex, Cursor, and Claude Code to https://mcp.algolia.com/1/docsearch/mcp for current public developer documentation.
Related projects
DocSearch is made of the following repositories:
- algolia/docsearch: DocSearch source code.
- algolia/docsearch/packages/website: DocSearch website and documentation.
- algolia/docsearch-configs: DocSearch websites configurations that DocSearch powers.
- algolia/docsearch-scraper: DocSearch crawler that extracts data from your documentation.
Used by
DocSearch is used by Bootstrap, Cheerio, Element Plus, Authelia, MDX, VitePress and many more.
Generated with usedby.dev
License
Packages Website Docs Agent Studio Getting Started (`packages/website/docs/agent-studio/getting-started.mdx`)
title: Get started with Agent Studio
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
DocSearch v5 uses Agent Studio as its only AI backend. The public option is still named askAi, so you can add AI without learning a second DocSearch configuration shape.
Don't add an agentStudio flag. There's no AI backend selector in v5.
If you already have an Ask AI assistant, see Migrate Ask AI to Agent Studio.
Before you begin
- Create and publish an Agent Studio agent.
- Copy its agent ID. DocSearch calls this value
agentIdin its public API. - Create a Search API key that can search the indices used by DocSearch and Agent Studio. Don't expose an Admin API key.
- Note your Algolia application ID and DocSearch index name.
Add DocSearch
Install the React package and styles:
npm install @docsearch/react@^5 @docsearch/css@^5yarn add @docsearch/react@^5 @docsearch/css@^5pnpm add @docsearch/react@^5 @docsearch/css@^5bun add @docsearch/react@^5 @docsearch/css@^5Render DocSearchAI, not the search-only DocSearch component:
import { DocSearchAI } from '@docsearch/react';
import '@docsearch/css';
export function Search() {
return (
<DocSearchAI
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_DOCSEARCH_INDEX']}
askAi={{
agentId: 'YOUR_AGENT_ID',
}}
/>
);
}See the React package reference for all DocSearchAI props and exported types.
Install the JavaScript package and styles:
npm install @docsearch/js@^5 @docsearch/css@^5yarn add @docsearch/js@^5 @docsearch/css@^5pnpm add @docsearch/js@^5 @docsearch/css@^5bun add @docsearch/js@^5 @docsearch/css@^5Add a container to your page:
<div id="docsearch"></div>Initialize DocSearch with your Agent Studio agent:
import docsearch from '@docsearch/js';
import '@docsearch/css';
docsearch({
container: '#docsearch',
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_DOCSEARCH_INDEX'],
askAi: {
agentId: 'YOUR_AGENT_ID',
},
});See the JavaScript package reference for the complete API.
Configure more Agent Studio features
Use the askAi object to add:
- Dynamic indices
- Client-side and MCP tools
- User-scoped memory
- Suggested prompts and follow-ups
- Response feedback
Use the Docusaurus adapter
The v5 Docusaurus adapter requires themeConfig.docsearch.askAi to be an object with agentId. It rejects the string shorthand and the removed agentStudio property. Keep appId, apiKey, and keyword-search indices at the top level.
See the Docusaurus adapter guide for its full configuration and validation rules.
Packages Website Docs Mcp Overview (`packages/website/docs/mcp/overview.mdx`)
title: DocSearch MCP sidebar_label: Overview
DocSearch MCP lets AI clients search public developer documentation in the DocSearch corpus.
Use it when an assistant needs information from published documentation instead of relying only on its training data. Connect an MCP-compatible client to this endpoint:
https://mcp.algolia.com/1/docsearch/mcpThe endpoint doesn't require authentication. You don't need an Algolia application ID, search API key, or DocSearch application.
What DocSearch MCP provides
DocSearch MCP exposes documentation search through the Model Context Protocol. Your client calls its tools, receives ranked documentation excerpts and source URLs, and uses those results to answer your question.
Use DocSearch MCP for public documentation about libraries, frameworks, SDKs, APIs, CLI tools, and cloud services. It doesn't provide access to:
- Private or unpublished documentation
- Internal repositories
- DocSearch crawler or administration operations
- Algolia indices or credentials
- General programming advice outside the indexed documentation
How searches work
For most searches, provide a product name and a focused question. DocSearch resolves the matching documentation set and searches it in one call.
Use the two-step workflow when a question covers several products or when you need to select the documentation set yourself. First resolve candidate sets, then query the selected set IDs.
Available tools
`algolia_docsearch_search_docs`
Use this one-shot tool for most searches. Set library to the official product, SDK, or platform name. Set query to the documentation question.
The tool resolves the best matching documentation set and returns ranked content. If the product name is ambiguous, it returns candidate documentation sets instead.
`algolia_docsearch_resolve_docset`
Use this tool first in the manual workflow. It returns candidate documentation sets with a docset_id, title, description, and ranking signals.
`algolia_docsearch_query_docs`
Use this tool with one or more docset_id values returned by algolia_docsearch_resolve_docset. Pass several IDs when the question covers more than one product.
Security and service limits
Connect only to the HTTPS endpoint shown on this page. Don't add Algolia credentials to the MCP configuration. Send documentation questions, not secrets or confidential data, to the hosted service.
DocSearch MCP searches public content and returns external documentation to your client. Review generated answers and commands before you use them.
:::note[Service terms]
Algolia DocSearch MCP is a free service and is provided by Algolia "AS IS" and "AS AVAILABLE" without warranty of any kind. Algolia may suspend, modify, or discontinue the service at any time at its sole discretion. Algolia disclaims all obligation and liability arising from or related to your use of DocSearch MCP. You must comply with all applicable laws and government regulations when you use the service.
:::
Next steps
Packages Website Docs Packages Overview (`packages/website/docs/packages/overview.mdx`)
title: DocSearch packages
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
DocSearch v5 provides keyword search, AI answers powered by Agent Studio, and lower-level packages for custom integrations.
Start with @docsearch/js for a browser integration or @docsearch/react for a React application. Both packages support the same keyword search options.
Choose a package
| Package | Use it for |
|---|---|
@docsearch/js |
JavaScript sites, including sites that don't use React. The default entry includes keyword search and Ask AI. |
@docsearch/react |
React applications. Choose DocSearch for keyword search or DocSearchAI for keyword search and Ask AI. |
@docsearch/css |
The complete button and modal stylesheet. See Styling. |
@docsearch/core |
Shared state, keyboard handling, and the provider for the Composable API. |
@docsearch/modal |
Search button, keyword modal, and Ask AI modal components for the Composable API. |
@docsearch/sidepanel |
React Sidepanel components for persistent AI conversations. |
@docsearch/sidepanel-js |
JavaScript wrapper for the AI Sidepanel. |
If your Docusaurus site uses the DocSearch adapter, follow the Docusaurus adapter guide.
Choose a search experience
Keyword search
Use keyword search when you only need results from Algolia indices. It has no Ask AI runtime.
- JavaScript: import
@docsearch/js/docsearch. - React: render
DocSearchfrom@docsearch/react.
Keyword search and Ask AI
Use the AI-capable integration when you have an Agent Studio assistant.
- JavaScript: use the default
@docsearch/jsexport. - React: render
DocSearchAIfrom@docsearch/react.
Create and configure the assistant before adding it to DocSearch. See Get started with Agent Studio.
Composable and hybrid experiences
Use the Composable API to control the provider, button, and modal separately. Use hybrid mode to combine the modal with the AI Sidepanel.
For an existing v4 integration, read Migrate from v4 and v5 breaking changes.
Packages Website Docs Packages Core Overview (`packages/website/docs/packages/core/overview.mdx`)
title: Core package
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
@docsearch/core provides the React state shared by DocSearch views. It owns open and close state, keyboard events, theme selection, lifecycle callbacks, initial queries, and imperative controls. It doesn't render a search interface by itself.
Install
npm install @docsearch/core@^5yarn add @docsearch/core@^5pnpm add @docsearch/core@^5bun add @docsearch/core@^5Packages such as @docsearch/modal and @docsearch/sidepanel consume this provider. For component composition instructions, see the Composable API guide.
Configure shared behavior
import { DocSearch } from '@docsearch/core';
export function SearchState({ children }: { children: React.ReactNode }) {
return (
<DocSearch
theme="dark"
initialQuery="authentication"
keyboardShortcuts={{
'Ctrl/Cmd+K': true,
'/': false,
'Ctrl/Cmd+I': true,
}}
onReady={() => track('docsearch_ready')}
onOpen={() => track('search_opened')}
onClose={() => track('search_closed')}
onSidepanelOpen={() => track('assistant_opened')}
onSidepanelClose={() => track('assistant_closed')}
>
{children}
</DocSearch>
);
}The default shortcuts enable Control/Command+K, /, and Control/Command+I. Slash doesn't open the modal while focus is in an input, select, textarea, or editable element.
Use a ref
import { DocSearch, type DocSearchRef } from '@docsearch/core';
import { useRef } from 'react';
export function SearchState({ children }: { children: React.ReactNode }) {
const ref = useRef<DocSearchRef>(null);
return (
<>
<button type="button" onClick={() => ref.current?.open()}>
Open search
</button>
<DocSearch ref={ref}>{children}</DocSearch>
</>
);
}The ref can open and close registered views and report their state. See the core API reference. For interactions between views, see Hybrid Mode.
Read provider state
Call useDocSearch only beneath DocSearch. The hook throws outside the provider.
import { useDocSearch } from '@docsearch/core';
export function SearchStatus() {
const { docsearchState, openModal, closeModal } = useDocSearch();
return (
<button
type="button"
onClick={docsearchState === 'ready' ? openModal : closeModal}
>
{docsearchState === 'ready' ? 'Open search' : 'Close search'}
</button>
);
}Use the higher-level modal and Sidepanel packages for their standard triggers. Read context directly when your interface needs custom controls.
Packages Website Docs Packages Docusaurus Adapter Getting Started (`packages/website/docs/packages/docusaurus-adapter/getting-started.mdx`)
title: Docusaurus adapter
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Use @docsearch/docusaurus-adapter to add keyword search, a search results page, Ask AI, and an Ask AI Sidepanel to Docusaurus.
Before you start
Collect these values:
- An Algolia application ID.
- A Search API key with access to your DocSearch indices.
- At least one DocSearch index name.
- An Agent Studio assistant ID if you want Ask AI or the Sidepanel. Follow Get started with Agent Studio to create one.
Use Node.js 20 or later, Docusaurus 3.10.2 or later in the Docusaurus 3 release line, and React 18 or 19.
Install the adapter
Install @docsearch/docusaurus-adapter@^5:
npm install @docsearch/docusaurus-adapter@^5yarn add @docsearch/docusaurus-adapter@^5pnpm add @docsearch/docusaurus-adapter@^5bun add @docsearch/docusaurus-adapter@^5Keep @docusaurus/preset-classic. Don't add @docusaurus/theme-search-algolia as another search integration.
Configure keyword search
Add the adapter to plugins. Configure it under themeConfig.docsearch:
export default {
plugins: ['@docsearch/docusaurus-adapter'],
themeConfig: {
docsearch: {
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: [{ name: 'YOUR_INDEX_NAME' }],
},
},
};indices is required and must contain at least one index. Use an object to set search parameters for one index:
indices: [
{
name: 'docs',
searchParameters: {
facetFilters: ['language:en'],
attributesToRetrieve: [
'content',
'hierarchy',
'type',
'url',
'version',
],
},
},
],Start Docusaurus and open the search modal. The adapter also creates /search and links to it from the modal. Change or disable that route with searchPage.
Add Ask AI
Set askAi to an object with your Agent Studio assistant ID:
export default {
plugins: ['@docsearch/docusaurus-adapter'],
themeConfig: {
docsearch: {
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: [{ name: 'YOUR_INDEX_NAME' }],
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
},
},
},
};The adapter uses Agent Studio for Ask AI. Pass an object, not an assistant ID string. It reuses the root appId, apiKey, and first keyword index unless you configure dynamic Agent Studio indices.
Add the Sidepanel
Set sidePanel at the root of docsearch. You must also configure askAi:
docsearch: {
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: [{ name: 'YOUR_INDEX_NAME' }],
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
},
sidePanel: true,
},Pass an object instead of true to configure its placement, width, questions, translations, memory, or indices. The modal and Sidepanel share the DocSearch provider. Review hybrid mode for their responsive behavior.
Next steps
- Review every adapter option in the configuration reference.
- Follow Migrate from v4 if your site uses
themeConfig.algolia,indexName, rootsearchParameters, oraskAi.sidePanel. - Review the package-level DocSearch v4 migration guide.
Packages Website Docs Packages Js Getting Started (`packages/website/docs/packages/js/getting-started.mdx`)
title: JS package
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
Use @docsearch/js to render DocSearch into an HTML element. The default entry includes keyword search and Ask AI. A separate entry includes keyword search only.
Before you start
Collect your Algolia application ID, Search API key, and index name. To add Ask AI, also create an assistant in Agent Studio and copy its assistant ID.
Install the packages
npm install @docsearch/js@^5 @docsearch/css@^5yarn add @docsearch/js@^5 @docsearch/css@^5pnpm add @docsearch/js@^5 @docsearch/css@^5bun add @docsearch/js@^5 @docsearch/css@^5Add a container where you want the search button:
<div id="docsearch"></div>Pass a container element or a selector that matches one. Don't pass an input; DocSearch renders the search button and input.
Add keyword search and Ask AI
Import the default entry and provide an askAi configuration:
import docsearch from '@docsearch/js';
import '@docsearch/css';
const search = docsearch({
container: '#docsearch',
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_INDEX_NAME'],
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
},
});The default entry bundles both experiences. askAi accepts an assistant ID string or a configuration object. See the JavaScript API reference.
Add keyword search only
Import the /docsearch entry to exclude Ask AI code:
import docsearch from '@docsearch/js/docsearch';
import '@docsearch/css';
const search = docsearch({
container: '#docsearch',
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_INDEX_NAME'],
});Load DocSearch from a CDN
Load the complete stylesheet and one JavaScript bundle. Both UMD bundles expose window.docsearch.
Keyword search and Ask AI
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@docsearch/css@^5/dist/style.css"
/>
<script src="https://cdn.jsdelivr.net/npm/@docsearch/js@^5/dist/umd/index.js"></script>
<script>
window.docsearch({
container: '#docsearch',
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_INDEX_NAME'],
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
},
});
</script>Keyword search only
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@docsearch/css@^5/dist/style.css"
/>
<script src="https://cdn.jsdelivr.net/npm/@docsearch/js@^5/dist/umd/docsearch.js"></script>
<script>
window.docsearch({
container: '#docsearch',
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_INDEX_NAME'],
});
</script>Don't load both UMD bundles on the same page. The second bundle replaces the same window.docsearch global.
Control the instance
docsearch() returns a DocSearchInstance:
const search = docsearch({
container: '#docsearch',
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_INDEX_NAME'],
askAi: 'YOUR_ASSISTANT_ID',
});
search.open();
search.close();
search.openAskAi({ query: 'How do I configure search?' });
// Unmount DocSearch when your application removes this view.
search.destroy();Use openAskAi() only with the default AI-capable entry.
Next steps
- Review every option in the JavaScript API reference.
- Add multiple indices, facets, or result badges in the React examples. The configuration options also apply to JavaScript.
- Customize the design in Styling.
- Combine the modal and Sidepanel in hybrid mode.
Packages Website Docs Packages Modal Overview (`packages/website/docs/packages/modal/overview.mdx`)
title: Modal package
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
@docsearch/modal provides the DocSearch search button, keyword-search modal, and Agent Studio-enabled modal for React. Render these components inside the DocSearch provider from @docsearch/core.
For the complete component workflow, see the Composable API guide.
Install
npm install @docsearch/core@^5 @docsearch/modal@^5 @docsearch/css@^5yarn add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/css@^5pnpm add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/css@^5bun add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/css@^5Add keyword search
Import the main stylesheet once, near your application entry point.
import { DocSearch } from '@docsearch/core';
import { DocSearchButton, DocSearchModal } from '@docsearch/modal';
import '@docsearch/css';
export function Search() {
return (
<DocSearch>
<DocSearchButton />
<DocSearchModal
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']}
/>
</DocSearch>
);
}Use a search-only API key. Don't expose an Algolia Admin API key in browser code.
Add Agent Studio
In v5, Ask AI uses Agent Studio. Pass an Agent Studio agent ID through askAi. There's no agentStudio boolean in the v5 API.
import { DocSearch } from '@docsearch/core';
import { DocSearchAskAiModal, DocSearchButton } from '@docsearch/modal';
import '@docsearch/css';
export function Search() {
return (
<DocSearch>
<DocSearchButton />
<DocSearchAskAiModal
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']}
askAi="YOUR_AGENT_ID"
/>
</DocSearch>
);
}The askAi object also supports custom tools, conversation memory, and dynamic indices. See the DocSearchAskAiModal API.
Set provider options
The modal package reads theme, keyboard shortcut, and lifecycle state from DocSearch.
<DocSearch
theme="dark"
keyboardShortcuts={{ 'Ctrl/Cmd+K': true, '/': false }}
onOpen={() => track('search_opened')}
onClose={() => track('search_closed')}
>
<DocSearchButton />
<DocSearchModal
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']}
/>
</DocSearch>See the @docsearch/core API for provider props and refs.
Load smaller entry points
The package exposes component-specific entry points for code splitting:
import { DocSearchAskAiModal } from '@docsearch/modal/askai';
import { DocSearchButton } from '@docsearch/modal/button';
import { DocSearchModal } from '@docsearch/modal/modal';See the modal API reference for all exports and props.
Packages Website Docs Packages React Getting Started (`packages/website/docs/packages/react/getting-started.mdx`)
title: React package
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
@docsearch/react exports separate components for keyword search and Ask AI. Choose the component that matches your application.
Before you start
Collect your Algolia application ID, Search API key, and index name. To add Ask AI, create an assistant in Agent Studio and copy its assistant ID.
Install the packages
npm install @docsearch/react@^5 @docsearch/css@^5yarn add @docsearch/react@^5 @docsearch/css@^5pnpm add @docsearch/react@^5 @docsearch/css@^5bun add @docsearch/react@^5 @docsearch/css@^5The package supports React and React DOM versions from 16.8 through 19.
Add keyword search
Render DocSearch when your site only needs keyword results:
import { DocSearch } from '@docsearch/react';
import '@docsearch/css';
export function Search() {
return (
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']}
/>
);
}DocSearch doesn't include the Ask AI experience.
Add keyword search and Ask AI
Render DocSearchAI and pass the Agent Studio assistant:
import { DocSearchAI } from '@docsearch/react';
import '@docsearch/css';
export function Search() {
return (
<DocSearchAI
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']}
askAi={{
assistantId: 'YOUR_ASSISTANT_ID',
}}
/>
);
}askAi also accepts the assistant ID as a string. Use the object form for Agent Studio search parameters, dynamic indices, tools, memory, and prompt suggestions.
Control DocSearch with a ref
Both components forward a DocSearchRef:
import { useRef } from 'react';
import { DocSearchAI, type DocSearchRef } from '@docsearch/react';
export function Search() {
const searchRef = useRef<DocSearchRef>(null);
return (
<>
<button
type="button"
onClick={() =>
searchRef.current?.openAskAi({
query: 'How do I configure search?',
})
}
>
Ask about setup
</button>
<DocSearchAI
ref={searchRef}
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']}
askAi="YOUR_ASSISTANT_ID"
/>
</>
);
}Use open() and close() for keyword search. Sidepanel methods become useful when you register a Sidepanel through hybrid mode.
Next steps
- Review every component option in the React API reference.
- Start from the React examples for indices, facets, badges, templates, and refs.
- Use the Composable API for separate provider, button, and modal components.
- Customize the design in Styling.
- For Docusaurus, follow the Docusaurus adapter guide.
Packages Website Docs Packages Sidepanel Js Getting Started (`packages/website/docs/packages/sidepanel-js/getting-started.mdx`)
title: Sidepanel JS package
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
@docsearch/sidepanel-js mounts the Agent Studio Sidepanel into an existing HTML element. It bundles its rendering dependencies and returns an imperative instance.
Install
npm install @docsearch/sidepanel-js@^5 @docsearch/css@^5yarn add @docsearch/sidepanel-js@^5 @docsearch/css@^5pnpm add @docsearch/sidepanel-js@^5 @docsearch/css@^5bun add @docsearch/sidepanel-js@^5 @docsearch/css@^5Add a container to your page:
<div id="docsearch-sidepanel"></div>Mount the Sidepanel and retain the returned instance:
import sidepanel from '@docsearch/sidepanel-js';
import '@docsearch/css';
import '@docsearch/css/dist/sidepanel.css';
const assistant = sidepanel({
container: '#docsearch-sidepanel',
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
agentId: 'YOUR_AGENT_ID',
onReady() {
console.info('DocSearch sidepanel is ready');
},
});Use a search-only API key. The agentId is an Agent Studio agent ID.
Open with a question
Pass an initial message to open:
assistant.open({
query: 'How do I configure a search-only API key?',
});Call assistant.destroy() before removing the container or remounting another Sidepanel in it.
Load from a CDN
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@docsearch/css@^5/dist/style.css"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@docsearch/css@^5/dist/sidepanel.css"
/>
<div id="docsearch-sidepanel"></div>
<script src="https://cdn.jsdelivr.net/npm/@docsearch/sidepanel-js@^5/dist/umd/index.js"></script>
<script>
const assistant = docsearchSidepanel({
container: '#docsearch-sidepanel',
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
agentId: 'YOUR_AGENT_ID',
});
</script>See the JavaScript Sidepanel API for configuration, Agent Studio options, callbacks, and instance methods.
Packages Website Docs Packages Sidepanel Getting Started (`packages/website/docs/packages/sidepanel/getting-started.mdx`)
title: Sidepanel package
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
@docsearch/sidepanel provides composable React components for an Agent Studio chat panel.
Install
npm install @docsearch/core@^5 @docsearch/sidepanel@^5 @docsearch/css@^5yarn add @docsearch/core@^5 @docsearch/sidepanel@^5 @docsearch/css@^5pnpm add @docsearch/core@^5 @docsearch/sidepanel@^5 @docsearch/css@^5bun add @docsearch/core@^5 @docsearch/sidepanel@^5 @docsearch/css@^5Render the Sidepanel
Import both the main DocSearch stylesheet and the Sidepanel stylesheet.
import { DocSearch } from '@docsearch/core';
import { Sidepanel, SidepanelButton } from '@docsearch/sidepanel';
import '@docsearch/css';
import '@docsearch/css/dist/sidepanel.css';
export function HelpAssistant() {
return (
<DocSearch>
<SidepanelButton />
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
/>
</DocSearch>
);
}Use a search-only API key. The agentId is an Agent Studio agent ID. V5 doesn't provide the legacy Ask AI backend or an agentStudio switch.
The default button and panel float over the page. Press Control+I or Command+I to toggle the panel, and press Escape to close it.
Configure the provider
Set the theme and lifecycle callbacks on DocSearch.
<DocSearch
theme="dark"
keyboardShortcuts={{ 'Ctrl/Cmd+I': true }}
onSidepanelOpen={() => track('assistant_opened')}
onSidepanelClose={() => track('assistant_closed')}
>
<SidepanelButton variant="inline" />
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
/>
</DocSearch>Continue with advanced use cases or review the Sidepanel API. For a combined search and assistant experience, see Hybrid Mode.
Packages Website Docs Api (`packages/website/docs/api.mdx`)
title: API references
Choose the reference for the package in your application:
@docsearch/jsAPI@docsearch/reactAPI@docsearch/modalAPI@docsearch/sidepanelAPI@docsearch/sidepanel-jsAPI@docsearch/coreAPI- Docusaurus adapter configuration
For an end-to-end example, start with the package overview.
`container`
See the @docsearch/js API for the JavaScript container option.
Translations
See the React API for the shared translation structure.
`askAi`
See Get started with Agent Studio for AI configuration.
Packages Website Docs Composable Api (`packages/website/docs/composable-api.mdx`)
title: Composable API
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
The composable API gives you control over where DocSearch renders, when its modal code loads, and how the rest of your application opens or closes it.
Use this API in React applications. For the connected component reference, see the modal package overview.
Choose a modal
DocSearch v5 provides two modal components. Render one modal for each DocSearch provider.
| Component | Use it for |
|---|---|
DocSearchModal |
Keyword search without Ask AI |
DocSearchAskAiModal |
Keyword search and Ask AI in the same modal |
DocSearchAskAiModal includes keyword search. Don't render both modal components to add Ask AI.
The composable components come from three packages:
@docsearch/coreprovidesDocSearch, shared state, keyboard handling, and the imperative ref.@docsearch/modalprovides the provider-connected button and modal components.@docsearch/cssprovides the styles.
Install the packages
Install matching v5 versions of the DocSearch packages:
npm install @docsearch/core@^5 @docsearch/modal@^5 @docsearch/css@^5yarn add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/css@^5pnpm add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/css@^5bun add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/css@^5Add keyword search
Wrap the button and keyword modal in one DocSearch provider. Pass a public search-only API key to the provider; its descendants use these credentials by default.
import { DocSearch } from '@docsearch/core';
import { DocSearchButton, DocSearchModal } from '@docsearch/modal';
import type { JSX } from 'react';
import '@docsearch/css/dist/style.css';
interface KeywordSearchProps {
appId: string;
apiKey: string;
indexName: string;
}
export function KeywordSearch({
appId,
apiKey,
indexName,
}: KeywordSearchProps): JSX.Element {
return (
<DocSearch appId={appId} apiKey={apiKey}>
<DocSearchButton
translations={{
buttonText: 'Search docs',
buttonAriaLabel: 'Search documentation',
}}
/>
<DocSearchModal indices={[indexName]} />
</DocSearch>
);
}The provider opens the modal when a user selects the button, presses Ctrl/Command+K, or presses / outside an editable field. Closing the modal returns focus to DocSearchButton.
Add keyword search and Ask AI
Replace DocSearchModal with DocSearchAskAiModal. Create the assistant in Agent Studio, then configure its ID on the provider.
import { DocSearch } from '@docsearch/core';
import { DocSearchAskAiModal, DocSearchButton } from '@docsearch/modal';
import type { JSX } from 'react';
import '@docsearch/css/dist/style.css';
interface SearchWithAskAiProps {
appId: string;
apiKey: string;
indexName: string;
agentId: string;
}
export function SearchWithAskAi({
appId,
apiKey,
indexName,
agentId,
}: SearchWithAskAiProps): JSX.Element {
return (
<DocSearch appId={appId} apiKey={apiKey}>
<DocSearchButton />
<DocSearchAskAiModal
indices={[indexName]}
askAi={agentId}
/>
</DocSearch>
);
}The askAi prop accepts an assistant ID string or an object with agentId. Use the object form when you need options such as indices, searchParameters, suggestedQuestions, promptSuggestions, tools, or memory. Set appId and apiKey on an individual modal or Sidepanel only when they must override the provider's defaults.
Understand the shared state
DocSearch holds one state value and shares it with its descendants:
| State | Meaning |
|---|---|
ready |
No modal or Sidepanel is open. |
modal-search |
The keyword search view is open. |
modal-askai |
Ask AI is open in the modal. |
sidepanel |
The Ask AI Sidepanel is open. |
The connected components manage these transitions for you:
DocSearchButtoncalls its ownonClickhandler, then opens keyword search.- Each modal registers itself with the provider and renders in a React portal only while a modal state is active.
DocSearchModalreads the provider's initial query and close action.DocSearchAskAiModalalso reads and updates the Ask AI state.
Use useDocSearch in a component under the provider when your application needs declarative access to this state.
import { useDocSearch } from '@docsearch/core';
import type { JSX } from 'react';
export function SearchControls(): JSX.Element {
const { closeModal, docsearchState, openModal, onAskAiToggle } =
useDocSearch();
return (
<div>
<span>Search state: {docsearchState}</span>
<button type="button" onClick={openModal}>
Open search
</button>
<button type="button" onClick={() => onAskAiToggle(true)}>
Open Ask AI
</button>
<button type="button" onClick={closeModal}>
Close search
</button>
</div>
);
}Only call onAskAiToggle(true) when the provider contains DocSearchAskAiModal or a compatible Ask AI view.
Control DocSearch with a ref
Attach a DocSearchRef to the provider when non-React code or a parent component must control DocSearch.
import { DocSearch, type DocSearchRef } from '@docsearch/core';
import { DocSearchAskAiModal, DocSearchButton } from '@docsearch/modal';
import { useRef, type JSX } from 'react';
interface ControlledSearchProps {
appId: string;
apiKey: string;
indexName: string;
agentId: string;
onReady?: () => void;
onOpen?: () => void;
onClose?: () => void;
}
export function ControlledSearch(props: ControlledSearchProps): JSX.Element {
const searchRef = useRef<DocSearchRef>(null);
return (
<DocSearch
ref={searchRef}
onReady={props.onReady}
onOpen={props.onOpen}
onClose={props.onClose}
>
<DocSearchButton />
<button
type="button"
onClick={() =>
searchRef.current?.openAskAi({
query: 'How do I configure DocSearch?',
})
}
>
Ask a question
</button>
<DocSearchAskAiModal
appId={props.appId}
apiKey={props.apiKey}
indices={[props.indexName]}
askAi={props.agentId}
/>
</DocSearch>
);
}The ref exposes these methods and read-only values. initialMessage has a required query and optional messageId and suggestedQuestionId fields.
The provider accepts onReady, onOpen, onClose, onSidepanelOpen, and onSidepanelClose. onReady runs after mount. The other callbacks run once when their corresponding view changes state, not every time React renders.
`open`
type: () => void
Opens keyword search.
`close`
type: () => void
Returns the provider to ready.
`openAskAi`
type: (initialMessage?: InitialAskAiMessage) => void
Opens Ask AI in a registered Sidepanel on desktop, or in the modal otherwise.
`openSidepanel`
type: (initialMessage?: InitialAskAiMessage) => void
Opens a registered Sidepanel. It does nothing when no Sidepanel is registered.
`isReady`
type: readonly boolean
Reports whether the provider is mounted.
`isOpen`
type: readonly boolean
Reports whether a modal view is open.
`isSidepanelOpen`
type: readonly boolean
Reports whether the Sidepanel is open.
`isSidepanelSupported`
type: readonly boolean
Reports whether desktop hybrid mode is available.
Load the modal on demand
Import the button eagerly and split the larger modal into another JavaScript chunk. The following Ask AI example preloads that chunk on hover, focus, or touch, then renders it only after the provider opens a modal state.
/* Detailed source-code truncated for AI context efficiency. */Render the provider and connected components only in the browser. The modal wrappers read document.body and window.scrollY when they render.
Use the exact entry points
Use the package root for convenience or a subpath to keep eager bundles focused.
| Import | Exports |
|---|---|
@docsearch/core |
DocSearch, useDocSearch, their types, keyboard utilities, and theme utilities |
@docsearch/modal |
DocSearchButton, DocSearchModal, DocSearchAskAiModal, and their prop types |
@docsearch/modal/button |
DocSearchButton, DocSearchButtonProps |
@docsearch/modal/modal |
DocSearchModal, DocSearchModalProps |
@docsearch/modal/askai |
DocSearchAskAiModal, DocSearchAskAiModalProps |
The lower-level React entry points are @docsearch/react/button, @docsearch/react/modal, and @docsearch/react/askaiModal. They don't connect themselves to the composable provider. Use them only when you intend to manage portal rendering, refs, initialScrollY, close behavior, and Ask AI state yourself.
Load the styles
For either complete modal, import the combined stylesheet once:
import '@docsearch/css/dist/style.css';The combined stylesheet contains variables, button styles, keyword modal styles, and Ask AI modal styles. It doesn't contain Sidepanel styles.
For a keyword-only CSS bundle, import the layers in this order:
import '@docsearch/css/dist/_variables.css';
import '@docsearch/css/dist/button.css';
import '@docsearch/css/dist/modal.css';Add @docsearch/css/dist/_askai.css when you use DocSearchAskAiModal. Bundlers can also load the same files through @docsearch/react/style, @docsearch/react/style/button, @docsearch/react/style/modal, @docsearch/react/style/askai, and @docsearch/react/style/variables.
API summary
| API | Required configuration | Provider-managed behavior |
|---|---|---|
DocSearch |
children |
State, credentials defaults, theme, initial query, shortcuts, focus restoration, lifecycle callbacks, and DocSearchRef |
DocSearchButton |
None | Button ref, theme, shortcuts, and opening keyword search |
DocSearchModal |
At least one indices entry or deprecated indexName; appId and apiKey must be set here or on DocSearch |
Open state, close action, initial scroll position, initial query, theme, and shortcuts |
DocSearchAskAiModal |
The keyword modal configuration plus askAi |
Keyword modal behavior, Ask AI state, Ask AI transitions, and hybrid detection |
useDocSearch |
A parent DocSearch provider |
Reads the context and throws when used outside the provider |
DocSearchButton accepts native React button props and translations. The connected wrapper doesn't accept theme or keyboardShortcuts; set those on DocSearch.
Both connected modal wrappers accept the corresponding low-level modal options, except the state and lifecycle fields supplied by the provider. Explicit appId and apiKey props override their respective provider values. Consult the modal API before adding options.
Packages Website Docs Crawler Configuration Visual (`packages/website/docs/crawler-configuration-visual.mdx`)
title: Crawler interface
import useBaseUrl from '@docusaurus/useBaseUrl';
Use the Algolia Crawler interface to manage crawl settings and monitor indexing. These settings are separate from your installed DocSearch frontend package version.
DocSearch tab
The Crawler UI now includes a dedicated DocSearch tab. This tab provides everything you need to implement DocSearch on your site, including:
- Implementation code: Starter snippets for integrating DocSearch into your frontend. For v5, compare the snippet with the current package guide.
- API keys: Your unique Application ID and Search API Key for connecting to your Algolia index.
- Documentation links: Access to review your records, explore documentation, and join the support Discord.
Trigger a new crawl
Head over to the Overview section to start, restart or pause your crawls and view a real-time summary.
Monitor your crawls
The Monitoring section helps you find crawl errors or improve your search results.
Update your config
You can update your crawler configuration in two ways:
Visual configuration: Edit common options without writing code in the visual configuration interface.
Code editor: For advanced configuration, use the live code editor to modify your configuration and test URLs with the URL tester.
URL tester
From the editor, you can use the URL tester to debug selectors or see how the crawler interprets your site.
Suggestions
The Suggestions section in the Crawler UI provides actionable feedback to help you improve your crawl and data extraction. After each crawl, you'll see recommendations for:
- Fixing redirect or domain issues
- Addressing ignored or failed URLs
- Adding missing sitemaps
Each suggestion includes a description, a solution, and links to relevant documentation or monitoring tools.
Packages Website Docs Crawler (`packages/website/docs/crawler.mdx`)
title: DocSearch x Algolia Crawler
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Use this page to resolve common crawler questions. If you need more help, contact us on Discord or through Algolia support.
For more troubleshooting guidance, read the Crawler FAQ:
For questions related to the DocSearch program, please see our DocSearch program FAQ.
How often will you crawl my website?
Crawls are scheduled at a random time once a week. You can configure this schedule from the config file or trigger one manually from the Crawler interface.
Why do I have duplicate content in my results?
This can happen when you have more than one URL pointing to the same content, for example with ./docs, ./docs/ and ./docs/index.html.
Configure canonical URLs on your website. For more information, read Google's Consolidate duplicate URLs guide.
Use exclusionPatterns to exclude duplicate URL patterns.
Are the [`docsearch-scraper`][9] and [`docsearch-configs`][10] repositories still maintained?
The legacy scraper infrastructure is deprecated. You can still run a legacy scraper instance and use its index with the historical DocSearch v3 UI. For current frontend integrations, choose a DocSearch v5 package. The scraper or crawler version doesn't determine the frontend package version.
How do I migrate?
Every owner should have received a migration email from Algolia with the details. If you were not part of the previous
indexowners, or the maintainer has changed, you can request access via our support page.
Use the migration email to complete these steps:
- Join the Algolia application with the invite included in the email
- Update your frontend integration with the credentials received in the email. For v5, follow the JavaScript or React guide.
<Tabs
groupId="language"
aria-label="Programming language"
defaultValue="react"
values={[
{ label: 'React', value: 'react', },
{ label: 'JavaScript', value: 'js', },
]
}>
<DocSearch
appId="YOUR_NEW_ALGOLIA_APP_ID"
apiKey="YOUR_NEW_ALGOLIA_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']} // The index name doesn't change.
/>docsearch({
container: '#docsearch',
appId: 'YOUR_NEW_ALGOLIA_APP_ID',
apiKey: 'YOUR_NEW_ALGOLIA_SEARCH_API_KEY',
indices: ['YOUR_INDEX_NAME'], // The index name doesn't change.
});What should I do with my legacy config and credentials?
Use the credentials for your current Algolia application. Don't use legacy credentials for new frontend integrations.
You should use the dedicated web interface to make any changes to your index.
Why do I see two Algolia apps in my dashboard?
We did not remove access to the legacy DocSearch application (BH4D9OD16A) to give you the time to get familiar with our new infrastructure. BH4D9OD16A will remain available until the migration has been completed for all the DocSearch users.
Search yields no results
If your search does not yield any results, but there is no error in your browser developer tools, there might be an issue with your index.
Check the following settings:
Confirm that your crawler configuration matches your website structure.
Use a configuration template for your website generator as a starting point. Test your selectors with the URL tester.
Confirm that your index settings are current. If they aren't, the search preview displays a banner.
The crawler applies
index settingsonly when it creates an index, which keeps the Algolia dashboard as the source of truth. If you changed your configuration significantly or moved to a different website generator, delete the index from the Algolia dashboard before starting a new crawl.
Can I delete my crawler?
Don't delete the default crawler associated with your DocSearch application. Creating a replacement might not preserve the program configuration.
What if I delete my DocSearch Crawler?
Contact us on Discord or email us at the address below.
Can I use the crawler on password-protected sites?
The crawler included with DocSearch applications can't access password-protected sites that require a login. To crawl these sites, choose an Algolia plan and add a crawler. Pay-as-you-go plans include a crawler, but the free tier has usage limits.
Links related to the migration
Packages Website Docs Create Crawler (`packages/website/docs/create-crawler.mdx`)
title: Create a new crawler
import useBaseUrl from '@docusaurus/useBaseUrl';
Create a new crawler
:::info
DocSearch apps created after July 2, 2024 can use the Algolia Crawler UI to set up and manage crawls. This guide covers adding your domain, verifying ownership, creating a crawler, and running your first test crawl. Open the Crawler UI at dashboard.algolia.com/crawler.
If you signed up before July 2, 2024, you can still use the Crawler UI, but creating and managing a crawler is more streamlined for users who joined after that date.
Learn more about the Crawler interface.
:::
Add domains
- Sign in to the Algolia dashboard.
- In the left sidebar, select Data sources.
- Select Crawler:
- Click Add your domain and enter the domains or subdomains you want to crawl (e.g.,
example.com,www.example.com). - If you’ve already added a domain, click the Domains tab.
- Click Add your domain and enter the domains or subdomains you want to crawl (e.g.,
- Click Add domain.
Note: Verify your domain within 7 days of adding it. The DocSearch team must also approve the domain before you can crawl it.
Verify your domain
You must verify ownership of each domain you want to crawl. The default method is email verification, but you can also use a meta tag, HTML file, robots.txt, or DNS record.
Meta tag
- In the Meta tag tab, click Copy to copy the verification tag.
- Add the tag to your site's
<head>section. - Publish your site and click Verify now in the Crawler dashboard.
HTML file
- In the HTML file tab, click Copy to copy the verification file content.
- Save it as a new HTML file and upload it to your web server.
- Add the file’s URL in the dashboard and click Verify now.
robots.txt
- In the Robots.txt tab, click Copy to copy the verification code.
- Paste it into your site's
robots.txtfile. - Publish and click Verify now.
DNS
- In the DNS tab, copy the provided DNS TXT record.
- Add it to your DNS provider’s settings.
- Click Verify now after the record propagates (may take up to 72 hours).
Create a new crawler
After you verify your domain and the DocSearch team approves it:
- Go to the Crawler page in the dashboard.
- Click New Crawler and fill in:
- Crawler name (descriptive)
- App ID (your Algolia application ID)
- Start URL (usually your home page)
- Crawler template (choose a template or default)
- Click Create to finish and run a test crawl.
Run the test crawl
The initial crawl visits up to 100 URLs to test access and extraction. Monitor its progress on the Overview page. After it finishes, review the extracted records in the Algolia dashboard.
Creating a crawler doesn't install or select a DocSearch frontend version. After indexing, choose a DocSearch v5 package or framework integration.
Next steps
- Edit your crawler configuration for scheduled crawls, inclusion/exclusion rules, and extraction settings.
- Use the Crawler’s suggestions for further optimization.
- For more details, see the Algolia Crawler documentation.
Packages Website Docs Docsearch Program (`packages/website/docs/docsearch-program.md`)
title: DocSearch program
Use this page to learn about the DocSearch program. If you need more help, contact us on Discord or through Algolia support.
For questions about the DocSearch crawler, see the Crawler FAQ.
What do I need to install on my side?
After your content is indexed, add a DocSearch v5 frontend package with the application ID, Search API key, and index name from your Algolia application.
DocSearch uses the Algolia Crawler to index your content. Use the Crawler interface to create, monitor, edit, and start crawlers. For crawler questions, see the Crawler FAQ. Crawler configuration and frontend package versions are independent.
How much does it cost?
The DocSearch program is free.
Search infrastructure can be costly for open source projects, so the DocSearch program is free. In exchange, keep the "Search by Algolia" logo next to the search results.
If you can't display the logo, create an Algolia account and run DocSearch on your own. Depending on the size of your documentation, you might need a paid plan. Free plans can hold up to 10,000 records.
What data are you collecting?
We extract data from your website markup and store it in a custom JSON format in your Algolia DocSearch index. The selectors in your crawler configuration determine what data to extract.
As the website owner, you can access your Algolia application to review indexed data, analyze anonymized searches, and manage your team.
Where is my data hosted?
We host DocSearch data on Algolia servers with replicas around the world. For more information, see the Algolia infrastructure documentation and privacy policy.
How do I upgrade my DocSearch app?
Choose an option based on your goal.
Upgrade #1: I want a specific feature, like Rules, added to my existing DocSearch application
Contact Algolia support to discuss your requirements.
Upgrade #2: I want to remove the Algolia logo
Removing the logo makes the project ineligible for the free DocSearch program. Instead, host the open source legacy DocSearch crawler or use an Algolia API client. Both options require a new Algolia application, and usage charges may apply.
Upgrade #3: Algolia is awesome, I want to use it for my whole site
Contact the Algolia sales team to choose a plan. After creating your application, adapt a crawler configuration template for the new crawler.
Can I use DocSearch on non-doc pages?
The free DocSearch program crawls only documentation pages for open source projects and technical blogs. To index other parts of your website, create an Algolia account and choose one of these options:
- Run the DocSearch crawler on your own
- Use a DocSearch frontend package, a supported framework integration, or an Algolia API client
Can you index code samples?
Yes, but we do not recommend it.
Code samples can help users understand a method, but repeated boilerplate adds noise to search results.
A documentation website I like does not use DocSearch. What can I do?
If a documentation website does not use DocSearch, file an issue in its repository that explains how DocSearch could help. You can also contact us on Discord.
How did we build this website?
We built this website with Docusaurus. Endi helped inspire the project. Read our tribute to Endi.
Can I share the `apiKey` in my repo?
The apiKey from the DocSearch team is a search-only API key, so you can share it publicly and track it in version control. If you run the scraper yourself, create a search-only key and don't share your Admin API key.
Why is the email API key different in the dashboard?
Every Algolia application has a default "Search API Key" in the dashboard. That key lets you list indices, retrieve settings, and search every index in your application. For DocSearch applications, the acceptance email includes a search-only API key scoped to your DocSearch index. To recover this key, contact Algolia support.
How do I rotate my API keys?
Contact Algolia support.
Can I have multiple projects under the same Algolia application?
Use one Algolia application per project. Apply to the DocSearch program for each additional project.
Why?
The information of the initially applied project is used everywhere when we deploy your app:
- The scope of your API keys
- The name of your Algolia application/Crawler
- The indices we generate
- The allowed domains of your Crawler
This information helps us scope support requests to the correct project.
Support
:::caution
Before contacting support, read the relevant documentation.
Here are some links to help you:
- The Algolia Crawler documentation
- The Algolia Crawler FAQ
- The DocSearch FAQ
- The Algolia documentation
Visit Algolia Academy to learn more about Algolia.
:::
Algolia doesn't provide support for the DocSearch UI library, but support is available for these products:
- Contact Algolia support for the Algolia Crawler.
- Contact Algolia support for the Algolia dashboard.
For any issue related to the DocSearch UI library, please open a GitHub issue.
Packages Website Docs Docsearch (`packages/website/docs/docsearch.mdx`)
title: Get started with DocSearch
DocSearch v5 provides separate packages for JavaScript, React, composable interfaces, and framework integrations.
Start with the package overview to choose an integration:
- Use
@docsearch/jsfor a JavaScript application. - Use
@docsearch/reactfor a React application. - Use the Docusaurus adapter for a Docusaurus site.
- Use the Composable API to control the React interface.
To upgrade an existing integration, follow Migrating from v4.
Installation
Install instructions depend on your package. Open the package guide above for commands and required styles.
Packages Website Docs Docusaurus Adapter (`packages/website/docs/docusaurus-adapter.mdx`)
title: Docusaurus adapter
Use @docsearch/docusaurus-adapter to add DocSearch v5 to a Docusaurus site.
Packages Website Docs Examples (`packages/website/docs/examples.mdx`)
title: Examples
Use these guides for production-ready examples:
For JavaScript setup examples, see Get started with @docsearch/js.
Packages Website Docs How Does It Work (`packages/website/docs/how-does-it-work.mdx`)
title: How does it work?
import useBaseUrl from '@docusaurus/useBaseUrl';
DocSearch setup has three parts: join the DocSearch program, index your content, and add a frontend package or framework integration.
You apply
First, confirm that your website qualifies, then apply for DocSearch. The onboarding flow validates your domain against the program requirements.
If automated validation can't determine eligibility, the application might require a manual review.
Index your content
After approval, create a dedicated crawler in your Algolia application. Its configuration file defines which URLs to crawl, which URLs to ignore, and which selectors extract your content hierarchy.
Run a test crawl, review the extracted records, and configure recurring crawls. Use the Crawler interface to adjust the configuration as your website changes.
With the Crawler, comes a dedicated interface for you to:
- Start, schedule and monitor your crawls
- Edit and test your crawler configuration
With the Algolia application comes access to the dashboard for you to:
- Browse your index and see how your content is indexed
- Review analytics to understand how search performs
- Trials for other Algolia features
- Team management
Add DocSearch to your website
Choose a DocSearch v5 package or supported framework integration. Configure it with your application ID, Search API key, and index name. The frontend queries the Algolia index and displays the results.
Crawler versions, record schema versions, and frontend package versions are separate. In particular, crawler recordVersion: 'v3' describes the indexed record schema, not the DocSearch UI version. You can upgrade the v5 frontend packages without recreating the crawler. Keep the "Search by Algolia" logo next to your search results.
Packages Website Docs Hybrid Mode (`packages/website/docs/hybrid-mode.mdx`)
title: Hybrid mode
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
Hybrid mode starts in the DocSearch modal, then moves an Ask AI request into the Sidepanel. Users can scan keyword results in a focused overlay and continue an AI conversation beside the page.
The handoff carries the prompt and its identifiers. It doesn't submit the same prompt in both interfaces.
Prerequisites
Before you add hybrid mode:
- Use matching v5 DocSearch package versions.
- Configure a searchable Algolia index and a public search-only API key.
- Create an assistant in Agent Studio.
- Decide whether you need React, JavaScript, or the DocSearch Docusaurus adapter.
Read the package references for core, modal, Sidepanel, JavaScript, Sidepanel JavaScript, and the Docusaurus adapter when you need options beyond this workflow.
Understand the handoff
An Ask AI action can come from a typed prompt, a suggested question, a prompt suggestion in keyword results, or a saved conversation.
DocSearch represents the action as an InitialAskAiMessage:
interface InitialAskAiMessage {
query: string;
messageId?: string;
suggestedQuestionId?: string;
}Preserve the complete object during a manual handoff:
querybecomes the first prompt when the Sidepanel starts a conversation.suggestedQuestionIdis sent with the prompt so Agent Studio can identify the selected suggestion.messageIdlets the Sidepanel restore a locally stored conversation. If it can't find that conversation, it starts a new one withquery.
Add hybrid mode
React
Install the connected React packages and CSS:
npm install @docsearch/core@^5 @docsearch/modal@^5 @docsearch/sidepanel@^5 @docsearch/css@^5yarn add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/sidepanel@^5 @docsearch/css@^5pnpm add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/sidepanel@^5 @docsearch/css@^5bun add @docsearch/core@^5 @docsearch/modal@^5 @docsearch/sidepanel@^5 @docsearch/css@^5Render DocSearchAskAiModal and Sidepanel under the same DocSearch provider. The Sidepanel registers itself with the provider after mount. From then on, desktop Ask AI actions move to the Sidepanel automatically.
import { DocSearch } from '@docsearch/core';
import { DocSearchAskAiModal, DocSearchButton } from '@docsearch/modal';
import { Sidepanel, SidepanelButton } from '@docsearch/sidepanel';
import type { JSX } from 'react';
import '@docsearch/css/dist/style.css';
import '@docsearch/css/dist/sidepanel.css';
interface HybridSearchProps {
appId: string;
apiKey: string;
keywordIndexName: string;
agentId: string;
onReady?: () => void;
onOpen?: () => void;
onClose?: () => void;
onSidepanelOpen?: () => void;
onSidepanelClose?: () => void;
}
export function HybridSearch({
appId,
apiKey,
keywordIndexName,
agentId,
onReady,
onOpen,
onClose,
onSidepanelOpen,
onSidepanelClose,
}: HybridSearchProps): JSX.Element {
return (
<DocSearch
onReady={onReady}
onOpen={onOpen}
onClose={onClose}
onSidepanelOpen={onSidepanelOpen}
onSidepanelClose={onSidepanelClose}
>
<DocSearchButton />
<DocSearchAskAiModal
appId={appId}
apiKey={apiKey}
indices={[keywordIndexName]}
askAi={{ agentId }}
/>
<SidepanelButton />
<Sidepanel
appId={appId}
apiKey={apiKey}
agentId={agentId}
/>
</DocSearch>
);
}SidepanelButton gives users a direct Ask AI entry point. You can omit it without disabling hybrid handoff. Keep Sidepanel mounted so it can register before a user submits an Ask AI request.
React lifecycle callbacks
Put lifecycle callbacks on DocSearch so they observe the shared state.
During the automatic React handoff, the state changes directly from modal-askai to sidepanel. That transition calls onSidepanelOpen; it doesn't call onClose.
`onReady`
type: () => void| optional
Runs when the provider mounts.
`onOpen`
type: () => void| optional
Runs when a modal opens from ready or sidepanel.
`onClose`
type: () => void| optional
Runs when a modal changes directly to ready.
`onSidepanelOpen`
type: () => void| optional
Runs when the state changes to sidepanel.
`onSidepanelClose`
type: () => void| optional
Runs when the state leaves sidepanel.
JavaScript
The JavaScript packages create independent DocSearch and Sidepanel instances. Connect them with interceptAskAiEvent.
npm install @docsearch/js@^5 @docsearch/sidepanel-js@^5 @docsearch/css@^5yarn add @docsearch/js@^5 @docsearch/sidepanel-js@^5 @docsearch/css@^5pnpm add @docsearch/js@^5 @docsearch/sidepanel-js@^5 @docsearch/css@^5bun add @docsearch/js@^5 @docsearch/sidepanel-js@^5 @docsearch/css@^5Add one mount element for each instance:
<div id="docsearch"></div>
<div id="docsearch-sidepanel"></div>Create the Sidepanel first so the interceptor always has a target. The mobile check in this example matches the React integration: mobile users stay in the Ask AI modal, while desktop users move to the Sidepanel.
import docsearch, { type DocSearchInstance } from '@docsearch/js';
import sidepanel, { type SidepanelInstance } from '@docsearch/sidepanel-js';
import '@docsearch/css/dist/style.css';
import '@docsearch/css/dist/sidepanel.css';
const appId = 'YOUR_APP_ID';
const apiKey = 'YOUR_SEARCH_API_KEY';
const keywordIndexName = 'YOUR_KEYWORD_INDEX_NAME';
const agentId = 'YOUR_AGENT_ID';
const mobileQuery = window.matchMedia('(max-width: 768px)');
let search: DocSearchInstance | undefined;
let panel: SidepanelInstance | undefined;
panel = sidepanel({
container: '#docsearch-sidepanel',
appId,
apiKey,
agentId,
onReady: () => {
document.body.setAttribute('data-sidepanel-ready', '');
},
onOpen: () => {
search?.close();
document.body.setAttribute('data-sidepanel-open', '');
},
onClose: () => {
document.body.removeAttribute('data-sidepanel-open');
},
});
search = docsearch({
container: '#docsearch',
appId,
apiKey,
indices: [keywordIndexName],
askAi: agentId,
interceptAskAiEvent: (initialMessage) => {
if (mobileQuery.matches) {
return false;
}
search?.close();
panel?.open(initialMessage);
return true;
},
onReady: () => {
document.body.setAttribute('data-docsearch-ready', '');
},
onOpen: () => {
panel?.close();
document.body.setAttribute('data-search-open', '');
},
onClose: () => {
document.body.removeAttribute('data-search-open');
},
});The root @docsearch/js export includes Ask AI. The keyword-only JavaScript entry point is @docsearch/js/docsearch; don't use that entry point for hybrid mode because it has no Ask AI action to intercept.
How `interceptAskAiEvent` works
interceptAskAiEvent runs before the modal changes to Ask AI or sends a message.
- Return
trueafter another interface accepts the request. DocSearch clears the keyword query and skips all default Ask AI behavior. - Return
falseorundefinedto keep the default Ask AI modal flow. - Pass
initialMessageunchanged tosidepanelInstance.open(initialMessage)so conversation and suggestion IDs survive.
Keep the onOpen callbacks that close the other instance. They prevent two interfaces from staying open when application code calls search.open(), search.openAskAi(), or panel.open() directly.
The JavaScript instances expose these lifecycle callbacks and controls:
- The DocSearch instance accepts the
onReady,onOpen, andonClosecallbacks, and exposesopen(),close(),openAskAi(),destroy(),isReady, andisOpen. - The Sidepanel instance accepts the
onReady,onOpen, andonClosecallbacks, and exposesopen(),close(),destroy(),isReady, andisOpen.
Call both destroy() methods if your application removes the mount elements or tears down the page without a full navigation.
Add hybrid mode to Docusaurus
Hybrid mode is supported through @docsearch/docusaurus-adapter. The adapter loads the v5 modal and Sidepanel, connects their state, and applies the mobile behavior described in this guide.
Install the adapter and keep @docusaurus/preset-classic:
npm install @docsearch/docusaurus-adapter@^5yarn add @docsearch/docusaurus-adapter@^5pnpm add @docsearch/docusaurus-adapter@^5bun add @docsearch/docusaurus-adapter@^5Configure DocSearch under themeConfig.docsearch. Set top-level sidePanel to true or to a Sidepanel options object.
export default {
plugins: ['@docsearch/docusaurus-adapter'],
themeConfig: {
docsearch: {
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: [{ name: 'YOUR_INDEX_NAME' }],
askAi: {
agentId: 'YOUR_AGENT_ID',
},
sidePanel: true,
contextualSearch: true,
searchPage: { path: 'search' },
},
},
};The adapter requires askAi to be an object with agentId; it doesn't accept the string shorthand in Docusaurus configuration. It also requires askAi whenever sidePanel is set.
Don't put sidePanel inside askAi. Don't configure this adapter under themeConfig.algolia. If you need function-valued custom tools, pass them through a swizzled @theme/SearchBar component because Docusaurus removes functions while serializing theme configuration.
The built-in @docusaurus/theme-search-algolia integration doesn't provide this v5 Sidepanel configuration. Use the DocSearch adapter for this workflow.
Mobile behavior
The React provider treats viewports that match (max-width: 768px) as mobile. On those viewports, an Ask AI action stays in the modal even when a Sidepanel is registered. This avoids moving the conversation into the desktop Sidepanel layout.
The provider updates this decision on window resize. The Sidepanel also avoids focusing its prompt automatically on mobile because opening the virtual keyboard can disrupt the layout.
The JavaScript packages don't share a provider, so they don't apply the hybrid mobile decision to your interceptor. Add the matchMedia branch shown in the JavaScript example when you want the same behavior.
Load the styles
Hybrid mode needs both style bundles:
import '@docsearch/css/dist/style.css';
import '@docsearch/css/dist/sidepanel.css';style.css includes shared variables, the button, keyword modal, and Ask AI modal. sidepanel.css adds the Sidepanel layout and imports the shared variables it needs.
If your bundler resolves the React style entry points, @docsearch/react/style and @docsearch/react/style/sidepanel load the same bundles. Import each bundle once.
Troubleshoot hybrid mode
Ask AI stays in the modal on desktop
Confirm that Sidepanel is mounted under the same DocSearch provider before the Ask AI action. The provider enables automatic handoff only after the Sidepanel registers. Also confirm that the viewport is wider than 768 pixels.
Both the modal and Sidepanel submit the prompt
Return true from interceptAskAiEvent after calling panel.open(initialMessage). Returning false or no value tells the modal to continue its default flow.
Mobile users open the Sidepanel
In JavaScript integrations, check (max-width: 768px) in the interceptor and return false on a match. React and the Docusaurus adapter already make this decision.
The Sidepanel loses a suggestion or saved conversation
Pass the complete initialMessage object to open(). Rebuilding it with only query discards suggestedQuestionId and messageId.
A callback doesn't run during React handoff
Expect onSidepanelOpen, not onClose, when React changes directly from the modal to the Sidepanel. Use the shared provider callbacks rather than treating modal close as the handoff signal.
Two JavaScript interfaces remain open
Close the search instance in the Sidepanel's onOpen, and close the Sidepanel in the search instance's onOpen. This also covers programmatic calls that bypass the interceptor.
The interface is unstyled
Import both style.css and sidepanel.css. Check that your bundler includes CSS imports from dependencies.
Docusaurus rejects the configuration
Use themeConfig.docsearch, pass askAi as an object, and put sidePanel beside askAi. Install @docsearch/docusaurus-adapter@^5 instead of configuring hybrid mode through the built-in Algolia theme.
Server rendering fails with `window` or `document` errors
Mount the composable React components only in the browser. The Docusaurus adapter handles this boundary and lazy-loads the modal and Sidepanel client-side.
Packages Website Docs Integrations (`packages/website/docs/integrations.md`)
title: Supported integrations
Documentation frameworks can embed DocSearch in the websites they generate. A framework integration configures the frontend; your Algolia Crawler and index remain separate.
Framework integrations
If you use one of the following tools, follow its documentation to enable DocSearch. Framework documentation can target a different DocSearch frontend release, so check its package compatibility before adopting v5.
- Docusaurus v1 - How to enable search
- Docusaurus v2 and v3 - DocSearch v5 adapter / Using Algolia DocSearch
- VuePress - Algolia Search
- VitePress - Search
- Starlight - Algolia Search
- LaRecipe - Algolia Search
- Smooth DOC - DocSearch
- Docsy - Configure Algolia DocSearch
- Lotus Docs - Enabling the DocSearch Plugin
- Sphinx - Algolia DocSearch for Sphinx
If you maintain a similar tool and want us to add it to the list, open a pull request and contribute to Code Exchange.
Packages Website Docs Manage Your Crawls (`packages/website/docs/manage-your-crawls.mdx`)
title: Legacy crawler interface
:::caution
This crawler interface is deprecated and no longer maintained. It isn't a DocSearch frontend version. For current instructions, use the Crawler interface guide. Open the current interface at dashboard.algolia.com/crawler.
:::
import useBaseUrl from '@docusaurus/useBaseUrl';
DocSearch comes with the Algolia Crawler web interface that allows you to configure how and when your Algolia index will be populated.
Trigger a new crawl
Head over to the Overview section to start, restart or pause your crawls and view a real-time summary.
Monitor your crawls
The monitoring section helps you find crawl errors or improve your search results.
Update your config
The live editor allows you to update your config file and test your URLs (URL tester).
Search preview
The legacy editor's Search preview tab renders results with the historical DocSearch v3 frontend. This preview doesn't require your website to use that frontend version. For current integrations, see the v5 package guides.
URL tester
From the editor, your can use the URL tester to debug selectors or how we crawl your website.
Packages Website Docs Migrating From Legacy (`packages/website/docs/migrating-from-legacy.mdx`)
title: Migrating from the legacy scraper
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Introduction
This guide covers the historical migration from the self-hosted DocSearch scraper to the Algolia Crawler. It is separate from upgrading the frontend UI. For the current frontend, choose a DocSearch v5 package.
What's new?
Indexing infrastructure
DocSearch indexing now uses the Algolia Crawler. The DocSearch helper extracts records in place of the legacy DocSearch scraper.
You don't need to install local scraper tooling to maintain or update your index.
Use the legacy interface or the current Crawler interface to:
- Start, schedule and monitor your crawls
- Edit your config file from our live editor
- Test results with the historical DocSearch v3 or DocSearch v4 previews
These preview versions don't set the crawler record schema or the frontend package installed on your website. Likewise, crawler recordVersion: 'v3' names a record schema, not DocSearch UI v3.
Algolia application and credentials
We've received a lot of requests asking for:
- A way to manage team members
- Browse and see how Algolia records are indexed
- See and subscribe to other Algolia features
These features are available in your Algolia application.
FAQ
You can find answers related to the DocSearch migration in our Crawler FAQ page.
Useful links
Config file key mapping
Below are the keys that can be found in the legacy DocSearch configs and their translation to an Algolia Crawler config. For more detailed information on the Algolia Crawler, see the official documentation.
legacy |
current |
description |
|---|---|---|
start_urls |
startUrls |
Now accepts URLs only, see helpers.docsearch to handle custom variables |
page_rank |
pageRank |
Can be added to the recordProps in helpers.docsearch, should be passed as a string |
js_render |
renderJavaScript |
Unchanged |
js_wait |
renderJavascript.waitTime |
See documentation of renderJavaScript |
index_name |
removed, see actions |
Handled directly in the actions |
sitemap_urls |
sitemaps |
Unchanged |
stop_urls |
exclusionPatterns |
Supports micromatch |
selectors_exclude |
removed | Should be handled in the recordExtractor and helpers.docsearch |
custom_settings |
initialIndexSettings |
Unchanged |
scrape_start_urls |
removed | Can be handled with exclusionPatterns |
strip_chars |
removed | # are removed automatically from anchor links, edge cases should be handled in the recordExtractor and helpers.docsearch |
conversation_id |
removed | Not needed anymore |
nb_hits |
removed | Not needed anymore |
sitemap_alternate_links |
removed | Not needed anymore |
stop_content |
removed | Should be handled in the recordExtractor and helpers.docsearch |
Packages Website Docs Migrating From V4 (`packages/website/docs/migrating-from-v4.mdx`)
title: Migrate from DocSearch v4
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
DocSearch v5 separates keyword search from the AI experience and uses Agent Studio for Ask AI. Plan the migration around the experience your site provides.
Review the complete v5 breaking changes before releasing.
1. Upgrade packages
Upgrade every DocSearch package in the integration together with the ^5 range.
npm install @docsearch/react@^5 @docsearch/css@^5yarn add @docsearch/react@^5 @docsearch/css@^5pnpm add @docsearch/react@^5 @docsearch/css@^5bun add @docsearch/react@^5 @docsearch/css@^5npm install @docsearch/js@^5 @docsearch/css@^5yarn add @docsearch/js@^5 @docsearch/css@^5pnpm add @docsearch/js@^5 @docsearch/css@^5bun add @docsearch/js@^5 @docsearch/css@^5If you use the Composable API or Sidepanel, also upgrade @docsearch/core@^5, @docsearch/modal@^5, @docsearch/sidepanel@^5, or @docsearch/sidepanel-js@^5.
2. Choose keyword-only or AI-capable search
JavaScript without Ask AI
The v4 root export rendered the combined component. In v5, the root export is AI-capable and the /docsearch subpath is keyword-only.
Change the import:
-import docsearch from '@docsearch/js';
+import docsearch from '@docsearch/js/docsearch';Your keyword options can remain unchanged while you migrate deprecated options in a later step.
For a CDN integration, replace the root bundle with the keyword-only UMD file:
-<script src="https://cdn.jsdelivr.net/npm/@docsearch/js@4"></script>
+<script src="https://cdn.jsdelivr.net/npm/@docsearch/js@^5/dist/umd/docsearch.js"></script>JavaScript with Ask AI
Keep the root import. It now renders the AI-capable DocSearchAI component:
import docsearch from '@docsearch/js';
docsearch({
container: '#docsearch',
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_INDEX_NAME'],
askAi: {
agentId: 'YOUR_AGENT_ID',
},
});For a CDN integration, use dist/umd/index.js. It exposes window.docsearch, as v4 did.
React without Ask AI
Keep DocSearch, but remove any AI props. In v5 it renders keyword search only:
import { DocSearch } from '@docsearch/react';
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']}
/>;React with Ask AI
Replace DocSearch with DocSearchAI:
-import { DocSearch } from '@docsearch/react';
+import { DocSearchAI } from '@docsearch/react';
-<DocSearch
+<DocSearchAI
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_INDEX_NAME']}
askAi={{ agentId: 'YOUR_AGENT_ID' }}
/>DocSearchAI requires askAi. The string shorthand remains supported:
<DocSearchAI askAi="YOUR_AGENT_ID" {...searchProps} />3. Move Ask AI to Agent Studio
V5 removes the legacy Ask AI token and chat transport. Create the agent in Agent Studio before switching production traffic. If you already have an Ask AI assistant, follow Migrate Ask AI to Agent Studio.
Rename assistantId to agentId. Remove agentStudio from askAi. Agent Studio is the only Ask AI backend in v5.
askAi: {
- assistantId: 'YOUR_ASSISTANT_ID',
+ agentId: 'YOUR_AGENT_ID',
- agentStudio: true,
}The v4 Agent Studio form keyed search parameters by index name. V5 keeps that shape and removes the legacy flat form:
askAi: {
- assistantId: 'YOUR_ASSISTANT_ID',
+ agentId: 'YOUR_AGENT_ID',
searchParameters: {
- filters: 'language:en',
- attributesToRetrieve: ['title', 'content', 'url'],
+ docs: {
+ filters: 'language:en',
+ attributesToRetrieve: ['title', 'content', 'url'],
+ },
},
}Agent Studio search parameters support filters, attributesToRetrieve, restrictSearchableAttributes, and distinct. They don't support facetFilters in this object. Put fixed facet conditions in filters, or configure dynamic Agent Studio indices.
V5 adds askAi.indices, askAi.tools, askAi.memory, and askAi.promptSuggestions. Keep all Agent Studio configuration inside askAi. Keep interceptAskAiEvent at the component or docsearch() root because it controls view routing.
4. Move keyword configuration to `indices`
indexName and root searchParameters both have been removed in v5.
docsearch({
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
- indexName: 'docs',
- searchParameters: {
- facetFilters: ['language:en'],
- },
+ indices: [
+ {
+ name: 'docs',
+ searchParameters: {
+ facetFilters: ['language:en'],
+ },
+ },
+ ],
});Use one item per index. DocSearch queries them in array order.
5. Update result customization
Existing transformItems, hitComponent, resultsFooterComponent, transformSearchClient, navigation, Insights, and translation props remain available.
V5 changes the result markup and adds breadcrumbs, source sections, facets, and badges. Review custom CSS, DOM selectors, screenshots, and tests that depend on v4 markup.
To show a badge from a custom record property, add the property to the per-index attributesToRetrieve, then set resultBadgeKey:
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={[
{
name: 'docs',
searchParameters: {
attributesToRetrieve: [
'hierarchy.lvl0',
'hierarchy.lvl1',
'hierarchy.lvl2',
'hierarchy.lvl3',
'hierarchy.lvl4',
'hierarchy.lvl5',
'hierarchy.lvl6',
'content',
'type',
'url',
'version',
],
},
},
]}
resultBadgeKey="version"
/>6. Verify styles and package exports
The full stylesheet remains available from @docsearch/css and the CDN dist/style.css file:
import '@docsearch/css';The React package adds split style entries for variables, button, modal, Ask AI, and Sidepanel. See Styling.
@docsearch/js now defines an exports map. Replace unsupported deep imports with @docsearch/js or @docsearch/js/docsearch. Continue to use documented React subpaths such as @docsearch/react/button, /modal, /sidepanel, and /version; their generated file names changed, but the package subpaths remain the public API.
7. Verify programmatic controls
The JavaScript function returns a DocSearchInstance with open, close, openAskAi, destroy, isReady, and isOpen. Use openAskAi only with the default AI-capable entry.
React forwards DocSearchRef. It also exposes openSidepanel, isSidepanelOpen, and isSidepanelSupported for hybrid mode.
Test these cases before release:
- Open and close by button,
Ctrl/Cmd+K,/, and Escape. - Search every configured index and apply every facet.
- Open Ask AI, send follow-up questions, submit feedback, and restore a conversation.
- Exercise any custom tools and memory authentication.
- Verify custom hit links, result footers, translations, badges, and Insights events.
- Verify mobile behavior. Hybrid mode uses the modal instead of the Sidepanel on mobile.
8. Update framework integrations
If Docusaurus manages DocSearch configuration, follow the Docusaurus adapter guide. For custom provider, button, and modal layouts, review the Composable API.
Packages Website Docs Record Extractor (`packages/website/docs/record-extractor.md`)
title: Record Extractor
Introduction
:::info
This page documents the helpers.docsearch method. See the Algolia Crawler documentation for information about the Algolia Crawler.
:::
Set the recordExtractor parameter on an action to extract each page. Its function returns the data to index as an array of JSON objects.
The helpers are functions for extracting content and generating Algolia records.
Useful links
Usage
The most common way to use the DocSearch helper is to return its result to the recordExtractor function.
recordExtractor: ({ helpers }) => {
return helpers.docsearch({
recordProps: {
lvl0: {
selectors: "header h1",
},
lvl1: "article h2",
lvl2: "article h3",
lvl3: "article h4",
lvl4: "article h5",
lvl5: "article h6",
content: "main p, main li",
},
});
},Manipulate the DOM with Cheerio
The Cheerio instance ($) allows you to manipulate the DOM:
recordExtractor: ({ $, helpers }) => {
// Removing DOM elements we don't want to crawl
$(".my-warning-message").remove();
return helpers.docsearch({
recordProps: {
lvl0: {
selectors: "header h1",
},
lvl1: "article h2",
lvl2: "article h3",
lvl3: "article h4",
lvl4: "article h5",
lvl5: "article h6",
content: "main p, main li",
},
});
},Provide fallback selectors
Fallback selectors can be useful when retrieving content that might not exist in some pages:
recordExtractor: ({ $, helpers }) => {
return helpers.docsearch({
recordProps: {
// `.exists h1` will be selected if `.exists-probably h1` does not exists.
lvl0: {
selectors: [".exists-probably h1", ".exists h1"],
},
lvl1: "article h2",
lvl2: "article h3",
lvl3: "article h4",
lvl4: "article h5",
lvl5: "article h6",
// `.exists p, .exists li` will be selected.
content: [
".does-not-exists p, .does-not-exists li",
".exists p, .exists li",
],
},
});
},Provide raw text (`defaultValue`)
Only the lvl0 and custom variables selectors support this option
You might want to structure your search results differently than your website, or provide a defaultValue to a potentially non-existent selector:
recordExtractor: ({ $, helpers }) => {
return helpers.docsearch({
recordProps: {
lvl0: {
// It also supports the fallback DOM selectors syntax!
selectors: ".exists-probably h1",
defaultValue: "myRawTextIfDoesNotExists",
},
lvl1: "article h2",
lvl2: "article h3",
lvl3: "article h4",
lvl4: "article h5",
lvl5: "article h6",
content: "main p, main li",
// The variables below can be used to filter your search
language: {
// It also supports the fallback DOM selectors syntax!
selectors: ".exists-probably .language",
// Since custom variables are used for filtering, we allow sending
// multiple raw values
defaultValue: ["en", "en-US"],
},
},
});
},Indexing content for faceting
These selectors also support defaultValue and fallback selectors
To index content for frontend filters, such as version or language, define custom variables in recordProps. The helper adds them to each matching Algolia record:
recordExtractor: ({ helpers }) => {
return helpers.docsearch({
recordProps: {
lvl0: {
selectors: "header h1",
},
lvl1: "article h2",
lvl2: "article h3",
lvl3: "article h4",
lvl4: "article h5",
lvl5: "article h6",
content: "main p, main li",
// The variables below can be used to filter your search
foo: ".bar",
language: {
// It also supports the fallback DOM selectors syntax!
selectors: ".does-not-exists",
// Since custom variables are used for filtering, we allow sending
// multiple raw values
defaultValue: ["en", "en-US"],
},
version: {
// You can send raw values without `selectors`
defaultValue: ["latest", "stable"],
},
},
});
},The version, language, and foo attributes are then available in your records:
{
"foo": "valueFromBarSelector",
"language": ["en", "en-US"],
"version": ["latest", "stable"]
}Add every filter attribute to the index's attributesForFaceting, then expose up to five of them with the v5 facets option. If you display one with resultBadgeKey, also add that attribute to attributesToRetrieve; see the resultBadgeKey reference.
V5 result breadcrumbs use the hierarchy.lvl0 through hierarchy.lvl6 values generated from your selectors. Keep the heading levels ordered and include the hierarchy attributes in attributesToRetrieve.
Boost search results with `pageRank`
This parameter allows you to boost records using a custom ranking attribute built from the current pathsToMatch. Pages with highest pageRank will be returned before pages with a lower pageRank. The default value is 0 and you can pass any numeric value as a string, including negative values.
Search results are sorted by weight (desc), so you can have both boosted and non boosted results. The weight of each result will be computed for a given query based on multiple factors: match level, position, etc. and the pageRank value will be added to this final weight. The pageRank on its own may not be enough to influence the results of your query depending on how your overall ranking is set up. If changing the pageRank value doesn't influence your search results enough, even with large values, move weight.pageRank higher in the Ranking and Sorting page for your index.
You can view the computed weight directly from the Algolia dashboard (dashboard.algolia.com->search->perform a search->mouse hover over the "ranking criteria" icon bottom right of each record). That will give you an idea of what pageRank value is acceptable for your case.
{
indexName: "YOUR_INDEX_NAME",
pathsToMatch: ["https://YOUR_WEBSITE_URL/api/**"],
recordExtractor: ({ $, helpers, url }) => {
const isDocPage = /\/[\w-]+\/docs\//.test(url.pathname);
const isBlogPage = /\/[\w-]+\/blog\//.test(url.pathname);
return helpers.docsearch({
recordProps: {
lvl0: {
selectors: "header h1",
},
lvl1: "article h2",
lvl2: "article h3",
lvl3: "article h4",
lvl4: "article h5",
lvl5: "article h6",
content: "article p, article li",
pageRank: isDocPage ? "-2000" : isBlogPage ? "-1000" : "0",
},
});
},
},Reduce the number of records
If you encounter the Extractors returned too many records error when your page outputs more than 750 records, the aggregateContent option helps you reduce the number of records at the content level of the extractor.
{
indexName: "YOUR_INDEX_NAME",
pathsToMatch: ["https://YOUR_WEBSITE_URL/api/**"],
recordExtractor: ({ $, helpers }) => {
return helpers.docsearch({
recordProps: {
lvl0: {
selectors: "header h1",
},
lvl1: "article h2",
lvl2: "article h3",
lvl3: "article h4",
lvl4: "article h5",
lvl5: "article h6",
content: "article p, article li",
},
aggregateContent: true,
});
},
},Reduce the record size
If you encounter the Records extracted are too big error, your records or source page might contain too much information. The recordVersion option reduces record size by removing fields used only by the DocSearch v2 UI.
{
indexName: "YOUR_INDEX_NAME",
pathsToMatch: ["https://YOUR_WEBSITE_URL/api/**"],
recordExtractor: ({ $, helpers }) => {
return helpers.docsearch({
recordProps: {
lvl0: {
selectors: "header h1",
},
lvl1: "article h2",
lvl2: "article h3",
lvl3: "article h4",
lvl4: "article h5",
lvl5: "article h6",
content: "article p, article li",
},
recordVersion: "v3",
});
},
},`recordProps` API Reference
`lvl0`
type: Lvl0| required
type Lvl0 = {
selectors: string | string[];
defaultValue?: string;
};`lvl1`, `content`
type: string | string[]| required
`lvl2`, `lvl3`, `lvl4`, `lvl5`, `lvl6`
type: string | string[]| optional
`pageRank`
type: number| optional
See the live example
Custom variables
type: string | string[] | CustomVariable| optional
type CustomVariable =
| {
defaultValue: string | string[];
}
| {
selectors: string | string[];
defaultValue?: string | string[];
};Define custom variables in recordProps. You can use them with v5 facets and per-index filters.
`helpers.docsearch` API Reference
`aggregateContent`
type: boolean| default:true| optional
This option groups the Algolia records created at the content level of the selector into a single record for its matching heading.
`recordVersion`
type: 'v3' | 'v2'| default:v2| optional
This option selects the crawler record schema. It doesn't select the DocSearch UI package version. Set it to v3 to remove fields used only by the DocSearch v2 UI. The v3 value is also the current record schema for DocSearch v5 frontends.
`indexHeadings`
type: boolean | { from: number, to: number }| default:true| optional
This option tells the crawler if the headings (lvlX) should be indexed.
- When
false, only records for thecontentlevel will be created. - When
from, tois provided, only records for thelvlXtolvlYwill be created.
Packages Website Docs Required Configuration (`packages/website/docs/required-configuration.mdx`)
title: Required configuration
Follow these requirements so the crawler can extract structured records from your website. Update your markup and crawler configuration where needed.
:::info
If your website uses one of the supported framework integrations, its generated markup might already meet these requirements. Confirm that the crawler selectors match your framework and version.
:::
Generic configuration example
Start with the default DocSearch configuration template. For more customization options, see complex record extractors.
If you use a framework integration, see the configuration templates.
docsearch-default.js
/* Detailed source-code truncated for AI context efficiency. */recordVersion: 'v3' selects the crawler record schema. It isn't the DocSearch UI version and works with the v5 frontend packages. If you expose lang, language, or version as v5 facets, add those attributes to attributesForFaceting. Keep a badge attribute in attributesToRetrieve when you pass it to resultBadgeKey.
Overview of a clear layout
Use a page layout that separates documentation content from navigation and other page elements:
Use the main blue element as your .DocSearch-content container. Follow the next guidelines to structure its contents.
Use the right classes as [`recordProps`][2]
Add static classes to identify each content role. These classes don't need to change the page's appearance. The crawler uses them to extract structured records.
Add a static
DocSearch-contentclass to the main container for your text. This container is usually a<main>or<article>element.Configure every searchable
lvlelement outside the main documentation container, such as a sidebar item, as aglobalselector. The crawler adds these elements to every record from the page. Keep levels in increasing order in the document flow:lvlXshould followlvlYwhenX > Y.Use standard heading elements, such as
h1,h2, andh3, forlvlXselectors. You can also use static classes. Add a uniqueidornameattribute to each matching element.Give every element that matches an
lvlXselector a uniqueidornameattribute. DocSearch uses this anchor to open the page at the matching element.V5 builds result breadcrumbs from the populated
hierarchy.lvl0throughhierarchy.lvl6attributes. Keep heading levels ordered, avoid gaps where possible, and retrieve the fullhierarchyobject.Wrap every element that matches the
recordProps.contentselector in a `` or<li>element. Split text into focused blocks, and don't nest matching elements because this creates duplicate records.Keep the content structure consistent throughout the document.
Introduce global information as meta tags
The crawler automatically extracts information from DocSearch-specific meta tags:
<meta name="docsearch:language" content="en" />
<meta name="docsearch:version" content="1.0.0" />The crawler adds the content value of these meta tags to every record extracted from the page. Each tag's name attribute must follow the docsearch:$NAME pattern, where $NAME is the record attribute to set.
The docsearch:version meta tag can be a set of comma-separated tokens, each of which is a version relevant to the page. These tokens must be compliant with the SemVer specification or only contain alphanumeric characters (e.g. latest, next, etc.). As facet filters, these version tokens are case-insensitive.
For example, add the following meta tag to assign two versions to every record on a page:
<meta name="docsearch:version" content="2.0.0-alpha.62,latest" />The crawler adds the following version attribute to each record:
{
"version": ["2.0.0-alpha.62", "latest"]
}Add these attributes to attributesForFaceting. You can then use them in per-index facetFilters or expose up to five controls with the v5 facets option. To show version in each result, retrieve it and set resultBadgeKey to version.
Nice to have
Keep your sitemap up to date so the crawler can identify changed pages. The crawler also discovers eligible links from crawled pages.
Ensure that every page provides its full context. Use global elements where appropriate.
Make your documentation content available without client-side JavaScript rendering. If your website requires JavaScript rendering, set
renderJavaScript: truein your configuration.
Any questions? Connect with us on Discord or support.
Packages Website Docs Styling (`packages/website/docs/styling.md`)
title: Styling DocSearch
Use @docsearch/css to style DocSearch v5.
The package provides a complete stylesheet and separate bundles for the button, keyword modal, Ask AI interface, and sidepanel. See CSS bundles and exports to choose the files for your integration.
Packages Website Docs Templates (`packages/website/docs/templates.mdx`)
title: Config Templates
import useBaseUrl from '@docusaurus/useBaseUrl';
Use these crawler configuration templates as a starting point for supported website generators. To add or update a template, contact us on Discord or open a pull request.
If you want to better understand the default parameters of the configs below, take a look at the Crawler documentation.
Getting started
After approval, the onboarding flow creates a crawler with your URL and Algolia credentials. If it detects one of the listed generators, it can assign the matching template. Otherwise, it applies the default template.
These templates configure indexing, not the installed DocSearch frontend package. In a template, recordVersion: 'v3' means the crawler's v3 record schema; it doesn't mean DocSearch UI v3.
For v5 facets, add each custom filter attribute to attributesForFaceting and expose no more than five keys in the frontend. For resultBadgeKey, add the selected property to attributesToRetrieve. Keep hierarchy.lvl0 through hierarchy.lvl6 populated and retrievable so v5 can render result breadcrumbs. See the v5 JavaScript API reference.
Update a template
You can manually update the crawler template by going to dashboard.algolia.com, click "Data sources", select your crawler, and go to the editor page. From there you can edit the JavaScript directly. Note that you can make draft changes without saving, test the changes using the "URL Tester", and then "Save" once you're happy with your changes.
Default template
default.js
/* Detailed source-code truncated for AI context efficiency. */Docusaurus v1 template
docusaurus-v1.js
/* Detailed source-code truncated for AI context efficiency. */Docusaurus v2 and later template
docusaurus-v2.js
/* Detailed source-code truncated for AI context efficiency. */Astro Starlight Template
starlight.js
/* Detailed source-code truncated for AI context efficiency. */Vuepress v1 Template
vuepress-v1.js
/* Detailed source-code truncated for AI context efficiency. */Vuepress v2 Template
vuepress-v2.js
/* Detailed source-code truncated for AI context efficiency. */Vitepress Template
vitepress.js
/* Detailed source-code truncated for AI context efficiency. */Rspress Template
rspress.js
/* Detailed source-code truncated for AI context efficiency. */pkgdown Template
pkgdown.js
/* Detailed source-code truncated for AI context efficiency. */Packages Website Docs Tips (`packages/website/docs/tips.md`)
title: Tips for a good search
DocSearch works with many website structures, but consistent structure can improve relevance and indexing time. Follow these recommendations to improve your DocSearch results.
Use a `sitemap.xml`
If you provide a sitemap in your crawler configuration, DocSearch uses it to find pages to index. The crawler also follows eligible links on those pages.
Add a sitemap.xml to your website if you don't have one. A sitemap can reduce indexing time and gives you more control over which pages are indexed.
Sitemaps can also improve search engine optimization. For more information, see the sitemaps specification.
Structure the hierarchy of information
DocSearch works better on structured documentation. Result relevance uses the structural hierarchy of your content. The crawler reads the <h1> through <h6> headings or equivalent selectors to build hierarchy.lvl0 through hierarchy.lvl6.
Documentation usually introduces general concepts before covering details. Represent this structure with an ordered heading hierarchy. For example, content under an <h4> is more specific than content under an <h2> on the same page. Content that appears earlier on the page ranks higher.
DocSearch uses this structure to improve relevance. V5 also uses the populated hierarchy levels to render result breadcrumbs. Keep headings in order and avoid skipping levels where possible so each result retains its page context.
Choose a documentation depth that gives each result enough context. For large pages, use four levels, from lvl0 to lvl3. Use at least three levels.
You can use classes, such as ``, instead of <hX> elements.
Set a unique class to the element holding the content
DocSearch extracts content based on the HTML structure. We recommend that you add a custom class to the HTML element wrapping all your textual content. This will help narrow selectors to the relevant content.
A unique identifier makes your configuration more robust and limits indexing to relevant content. Use it to exclude unrelated headers, sidebars, and footers.
Add anchors to headings
Add a custom anchor to each heading. Define anchors with an id or name HTML attribute so browsers can scroll directly to the corresponding position. Links can target an anchor with # followed by its value.
DocSearch uses these anchors to send users to the location of the selected result.
Mark active pages in the navigation
If you use multi-level navigation, mark each active level with a custom CSS class. The crawler can use this class to determine where the current page fits in the website hierarchy.
For example, if your troubleshooting.html page is located under the "Installation" menu in your sidebar, we recommend that you add a custom CSS class to the "Installation" and "Troubleshooting" links in your sidebar.
Use any valid CSS class name that can be part of a CSS selector.
Consistency of your content
Use the same heading structure across documentation pages. Make each page topic and outline clear, and avoid selectors that create records without enough context, such as standalone introductions or asides.
Write selectors that match documentation pages but exclude landing pages, tables of contents, and other unrelated content. Add a dedicated class, such as .DocSearch-content, to the main documentation container.
Use consistent terms for the same concepts. You can also configure synonyms for terms your users search interchangeably.
Avoid duplicate content
Split broad topics into focused pages. Avoid catch-all pages that make it difficult to identify the relevant result.
Duplicate content adds noise and can mislead users. Don't repeat all documentation content on a landing or summary page. If you need duplicate records for separate datasets, such as different versions, use facets to distinguish them.
Index metadata for v5
Add each attribute used by the v5 facets option to attributesForFaceting. DocSearch supports up to five facet controls. For a result badge, index a short value such as version, include it in attributesToRetrieve, and pass its property path to resultBadgeKey. See the v5 JavaScript API reference.
Conciseness
Keep content focused on one task or concept, and use short headings and paragraphs.
For more guidance, read How to build a helpful search for technical documentation.
Packages Website Docs V5 Breaking Changes (`packages/website/docs/v5-breaking-changes.mdx`)
title: v5 breaking changes
This page lists the user-facing changes between the v4.6.0 package source and 5. Use it with the v4 migration guide.
JavaScript entry points
The root export is AI-capable
In v4, the root @docsearch/js export rendered the combined component and allowed Ask AI to be omitted. In v5, it renders DocSearchAI, and its DocSearchProps type requires askAi.
Use the root entry when you configure Agent Studio:
import docsearch from '@docsearch/js';Keyword-only search moved to `/docsearch`
Use the new subpath when you don't need Ask AI:
import docsearch from '@docsearch/js/docsearch';This entry excludes Ask AI code.
The UMD bundle is split
dist/umd/index.jsincludes keyword search and Ask AI.dist/umd/docsearch.jsincludes keyword search only.- Both bundles expose
window.docsearch. - Loading both bundles causes the later script to replace the same global.
An exports map restricts JavaScript imports
@docsearch/js now exports only . and ./docsearch. Replace imports of internal distribution files with one of these public entry points. Direct CDN URLs to the two documented UMD files remain supported by the package layout.
React components
`DocSearch` is keyword-only
V4's DocSearch accepted askAi and interceptAskAiEvent. V5's DocSearch contains keyword search only and no longer declares those props.
`DocSearchAI` owns the AI experience
Use DocSearchAI for keyword search and Ask AI:
import { DocSearchAI } from '@docsearch/react';DocSearchAIProps extends DocSearchProps, requires askAi, and adds interceptAskAiEvent.
The package also adds @docsearch/react/docsearchAi and @docsearch/react/askaiModal subpaths.
The Ask AI modal is separate
DocSearchModal is keyword-only. DocSearchAskAiModal contains the combined keyword and AI modal. Composable integrations that rendered DocSearchModal with askAi must switch to DocSearchAskAiModal and its required provider callbacks. Review the Composable API instead of constructing these props without the provider.
@docsearch/modal exports the AI modal from its root and from @docsearch/modal/askai.
Ask AI and Agent Studio
The legacy transport is removed
V5 no longer requests a legacy Ask AI token or sends chat requests to the v4 Ask AI endpoint. All Ask AI conversations use the Agent Studio completions endpoint.
Create and configure an assistant in Agent Studio before upgrading.
`askAi.agentStudio` is removed
The backend switch is no longer needed because Agent Studio is the only backend. Remove both agentStudio: true and agentStudio: false.
Flat Ask AI search parameters are removed
DocSearchAskAi.searchParameters now always uses AgentStudioSearchParameters: an object keyed by index name.
searchParameters: {
docs: {
filters: 'language:en',
attributesToRetrieve: ['title', 'content', 'url'],
distinct: true,
},
}Each value supports filters, attributesToRetrieve, restrictSearchableAttributes, and distinct. The Agent Studio type omits facetFilters.
Agent Studio credentials are sent directly
Ask AI requests use the configured application ID and API key in x-algolia-application-id and x-algolia-api-key headers. Memory authentication adds x-algolia-secure-user-token. Check the permissions and domain restrictions of keys that were issued for the legacy transport.
Feedback uses Agent Studio
Feedback now posts to Agent Studio and supports negative-feedback reason tags and notes. Stored conversation messages can contain feedbackTags and feedbackNotes in addition to the like or dislike value.
Agent Studio configuration is nested under `askAi`
Dynamic indices, custom tools, memory, and keyword promptSuggestions belong inside the askAi object. interceptAskAiEvent remains a top-level integration callback.
Suggested questions have two sources
askAi.suggestedQuestionsdetermines whether DocSearch loads published questions for the assistant fromalgolia_ask_ai_suggested_questionson the new-conversation screen.askAi.promptSuggestionssearches a configured index containing apromptattribute and displays those prompts with keyword results.
These options aren't interchangeable.
Search configuration
The Docusaurus adapter configuration changed
The v5 adapter reads themeConfig.docsearch and rejects the former themeConfig.algolia key. It also requires indices and rejects indexName and root searchParameters.
Replace searchPagePath with searchPage. Move askAi.sidePanel to the root sidePanel option. Remove legacy Ask AI credentials and the askAi.agentStudio switch. Follow Migrate the Docusaurus adapter from v4 for before-and-after configurations.
Multiple indices share one result flow
V5 creates one source for each index response and combines hit totals across responses. Result order follows the normalized index order. Review code that assumes one index or source identifier.
New keyword search behavior
Facets add requests and filters
The new facets option fetches facet values with a zero-hit query for every configured index. DocSearch merges and sorts values, supports at most five keys after trimmed, lowercase duplicate checks, and displays only facets with values.
A selected value is appended to that index's existing facetFilters. Account for the additional facet-value request in analytics, rate estimates, and search-client mocks.
Result badges require retrieved attributes
The new resultBadgeKey reads a property path from each hit. The default attributesToRetrieve list doesn't include custom badge properties. Add them to each relevant index's searchParameters.attributesToRetrieve.
Result markup and grouping changed
V5 refreshes the modal and result markup, renders breadcrumbs, introduces source panels, and adds facet and badge elements. CSS selectors, DOM tests, snapshots, and custom overrides that target v4 internals can break.
Use public component props for behavior and review Styling for visual changes.
Styles and builds
Ask AI styles have a separate source bundle
The complete @docsearch/css stylesheet still imports button, modal, and Ask AI rules. React also exposes split style entries:
@docsearch/react/style/variables@docsearch/react/style/button@docsearch/react/style/modal@docsearch/react/style/askai@docsearch/react/style/sidepanel
If you assemble styles by component, add style/askai for DocSearchAI or DocSearchAskAiModal.
Generated React file names changed
The documented package subpaths remain stable, but their targets changed from names such as dist/esm/DocSearchModal.js to generated entry files such as dist/esm/modal.js. Imports that bypassed the package exports can break.
The React `main` field now points to ESM
@docsearch/react changes main from dist/umd/index.js to dist/esm/index.js. Consumers that resolve main instead of the package exports need an ESM-compatible build pipeline. The explicit unpkg and jsdelivr fields continue to point to dist/umd/index.js.
The browser target is ES2017
V5's tsdown builds target ES2017. Provide transpilation or polyfills if your browser support policy extends below that target.
Public controls
JavaScript instances don't expose Sidepanel state
DocSearchInstance exposes open, close, openAskAi, destroy, isReady, and isOpen. It doesn't expose openSidepanel, isSidepanelOpen, or isSidepanelSupported.
React refs include Sidepanel controls
DocSearchRef exposes the JavaScript-style modal controls plus openSidepanel, isSidepanelOpen, and isSidepanelSupported. openSidepanel does nothing until a Sidepanel view registers. On mobile, openAskAi and standard Ask AI actions fall back to the modal.
See hybrid mode for the supported integration.
Deprecated keyboard hook fields remain
UseDocSearchKeyboardEventsProps.onInput and searchButtonRef are accepted for compatibility but are deprecated and aren't used by the v5 React hook implementation.
Compatibility
React peer range
@docsearch/react, @docsearch/core, @docsearch/modal, and @docsearch/sidepanel declare these optional peers:
react:>=16.8.0 <20.0.0react-dom:>=16.8.0 <20.0.0@types/react:>=16.8.0 <20.0.0
@docsearch/react also accepts optional search-insights versions >=1 <3.
Package versions must match
The v5 packages depend on matching versions of the other DocSearch packages. Don't mix v4 and v5 packages in a Composable API or Sidepanel tree.
CSS remains a separate install for top-level integrations
Install @docsearch/css@^5, then import @docsearch/css. For a CDN integration, load @docsearch/css/dist/style.css.
Additive v5 APIs
These additions aren't breaking by themselves, but they replace common v4 custom implementations:
facetsandDocSearchFacetfor keyword filters.resultBadgeKeyfor hit metadata.DocSearchAIandDocSearchAskAiModalfor AI-capable React views.askAi.indices(string[]) for dynamic Agent Studio search indices.askAi.searchParametersfor per-index runtime search overrides.ToolCallsandToolDefinitionfor custom Agent Studio tools.Memoryfor user-scoped Agent Studio memory.PromptSuggestionsfor keyword-query prompt suggestions.- Ask AI feedback tags and notes.
- Split JavaScript, React, and style entries for smaller keyword-only builds.
Packages Website Docs What Is Docsearch (`packages/website/docs/what-is-docsearch.md`)
title: What is DocSearch? sidebar_label: What is DocSearch?
Why?
We created DocSearch because developers spend a lot of time reading documentation, and finding relevant information in large documentation sites can be difficult. Building good search is a challenge.
Algolia has extensive experience building search interfaces. We use that experience to extract content from technical documentation and make it searchable from the first keystroke.
Overview
DocSearch has two independent parts: indexing and the frontend search experience.
- The Algolia Crawler extracts your documentation into an Algolia index. Use the Crawler interface to edit the crawler configuration, monitor crawls, and trigger new crawls.
- The DocSearch v5 packages query that index and render keyword search or Ask AI in your frontend. They are built on Algolia Autocomplete.
Crawler configuration and record schema versions don't select the installed DocSearch frontend package version. You can update the frontend package without changing how the crawler is scheduled.
How to feature DocSearch?
DocSearch is free for eligible documentation sites. Read the eligibility requirements and apply. After approval and indexing, add a DocSearch v5 package or a supported framework integration to your website. Keep the "Search by Algolia" link displayed.
DocSearch is one of our ways to give back to the open source community for everything it did for us already.
You can now apply to the program
Packages Website Docs Who Can Apply (`packages/website/docs/who-can-apply.md`)
title: Who can apply?
Open to developer documentation and technical blogs.
We built DocSearch to improve search on large technical documentation sites. We offer the free DocSearch program to public technical documentation and technical blogs.
We usually turn down applications when they are not production ready or have non-technical content on the website.
Application process
To apply to the DocSearch program, follow the onboarding process in the Algolia dashboard. Submit your domain for validation against the program requirements. If your domain meets the criteria, you can create your DocSearch crawler.
Use one of our supported integrations or a DocSearch v5 package after your content is indexed.
Verify your domain ownership within 7 days of approval to continue using the crawler.
Review the DocSearch Plan Terms and Conditions.
Process duration
The application process includes automated validation. If we can't determine your eligibility automatically, we'll conduct a manual review that may take one to two business days.
Once approved, continue the onboarding process to create your DocSearch crawler. After the crawler indexes your data, choose the frontend package or framework integration separately. Updating the frontend doesn't change your crawler or index format.
Packages Website Docs Agent Studio Dynamic Indices (`packages/website/docs/agent-studio/dynamic-indices.mdx`)
title: Configure dynamic indices
Pass askAi.indices when Agent Studio should search a specific set of indices for this request. This lets each DocSearch instance choose which indices the agent can use.
This property isn't the same as the top-level indices property:
- Top-level
indicesconfigures DocSearch keyword search. Entries are index names or objects with anameproperty. askAi.indicesconfigures Agent Studio search. Entries are index name strings.
Agent Studio completions accept index names only. Put index descriptions and tool defaults on the agent configuration in Agent Studio. Put per-index runtime overrides in askAi.searchParameters.
The agent's Algolia Search tool must use mode: "dynamic". If the tool's static index list is empty, also enable allowUnlistedIndices.
Select indices
<DocSearchAI
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['docs']}
askAi={{
agentId: 'YOUR_AGENT_ID',
indices: ['docs_markdown', 'api_reference'],
searchParameters: {
docs_markdown: {
filters: 'visibility:public',
attributesToRetrieve: ['title', 'content', 'url'],
},
api_reference: {
distinct: false,
},
},
}}
/>`indices`
type: string[]| optional
Index names available to the Agent Studio search tool for this request. When omitted, Agent Studio uses the indices configured on the agent tool.
Set request-wide search parameters
askAi.searchParameters is keyed by index name:
askAi: {
agentId: 'YOUR_AGENT_ID',
indices: ['docs_markdown'],
searchParameters: {
docs_markdown: {
filters: 'visibility:public',
attributesToRetrieve: ['title', 'content', 'url'],
distinct: false,
},
},
}Supported override fields are filters, attributesToRetrieve, restrictSearchableAttributes, distinct, userToken, enablePersonalization, personalizationImpact, and optionalFilters.
Don't use the flat search-parameter shape from earlier DocSearch AI integrations.
Docusaurus validation
The v5 Docusaurus adapter requires at least one string when you set askAi.indices. Contextual search merges version/language filters into askAi.searchParameters[index].filters for each dynamic index name.
See the React package reference and Docusaurus adapter guide for the complete types.
Packages Website Docs Agent Studio Feedback (`packages/website/docs/agent-studio/feedback.mdx`)
title: Collect response feedback
DocSearch v5 includes feedback controls for completed Agent Studio answers. You don't need to add an askAi option to enable them.
Use an API key with the search ACL. Agent Studio accepts one vote per message. See Agent Studio feedback for service requirements and reporting details.
Understand the ratings
Thumbs up submits positive feedback immediately:
{
thumbs: 1;
}Thumbs down opens a form before submission. A user can select zero or more reason tags and add an optional note:
{
thumbs: 0;
tags?: AskAiFeedbackReason[];
notes?: string;
}Closing or canceling the form doesn't submit feedback. Submitting without a reason or note is valid. DocSearch trims notes, omits an empty note, and limits notes to 1,000 characters.
DocSearch supports these reason values:
| Value | Default label |
|---|---|
incorrect |
Incorrect or incomplete |
not_what_i_asked |
Not what I asked for |
slow_or_buggy |
Slow or buggy |
style_or_tone |
Style or tone |
safety_or_legal |
Safety or legal concern |
other |
Other |
Reason tags and notes are collected only for negative feedback.
Understand submission behavior
DocSearch sends the Agent Studio agent ID, message ID, vote, and optional negative-feedback details to Agent Studio. After a successful request, it shows a thank-you state and records the rating with the locally stored conversation.
If submission fails, DocSearch keeps the negative-feedback form open and displays the error so the user can retry.
Change feedback labels
Override feedback text through translations.modal.askAiScreen:
<DocSearchAI
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['docs']}
askAi={{ agentId: 'YOUR_AGENT_ID' }}
translations={{
modal: {
askAiScreen: {
likeButtonTitle: 'Helpful',
dislikeButtonTitle: 'Not helpful',
thanksForFeedbackText: 'Feedback received',
feedbackPanelTitle: 'Tell us what went wrong',
feedbackDetailsPlaceholder: 'Add details',
feedbackSubmitButtonText: 'Send feedback',
feedbackTagIncorrect: 'Incorrect or incomplete',
feedbackTagNotWhatIAsked: 'Not what I asked for',
feedbackTagSlowOrBuggy: 'Slow or buggy',
feedbackTagStyleOrTone: 'Style or tone',
feedbackTagSafetyOrLegal: 'Safety or legal concern',
feedbackTagOther: 'Other',
},
},
}}
/>See the React package reference for all feedback translation keys and the exported feedback types.
Packages Website Docs Agent Studio Memory (`packages/website/docs/agent-studio/memory.mdx`)
title: Add user-scoped memory
Agent Studio memory lets an agent retain useful context for a user across conversations. Configure memory in Agent Studio first, then give DocSearch a secure user token so Agent Studio can isolate each user's data.
Read the Agent Studio memory overview before enabling memory in production.
Generate a secure user token
Generate the JWT on your backend after authenticating the user. Follow the Agent Studio user authentication guide for the required claims, signing algorithm, and key ID.
Protect the token flow:
- Never generate the token in browser code.
- Never expose the Algolia secret key used to sign it.
- Use a stable, non-sensitive user identifier in the JWT
subclaim. - Set an expiration and refresh expired tokens.
- Serve the token only over HTTPS.
- Don't put sensitive user data in JWT claims. JWT payloads aren't encrypted.
Pass the token to DocSearch
Fetch a token from your backend and pass it as memory.userToken:
const response = await fetch('/api/agent-studio-token', {
credentials: 'include',
});
const { userToken } = await response.json();
docsearch({
container: '#docsearch',
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['docs'],
askAi: {
agentId: 'YOUR_AGENT_ID',
memory: {
enabled: true,
userToken,
},
},
});Use the same askAi.memory object with React's DocSearchAI.
When userToken is present, DocSearch sends it in the X-Algolia-Secure-User-Token request header. When it's absent, DocSearch omits the header. Don't use unscoped memory for a multi-user application.
`memory.enabled`
type: boolean| optional
Controls whether DocSearch displays Agent Studio's built-in memory tool activity:
algolia_memorizedisplays that information was saved.algolia_ponderandalgolia_memory_searchdisplay that memory was used.- Memory tool errors aren't displayed.
The default is false.
This option doesn't enable memory in Agent Studio and doesn't create a user identity. Configure the feature on the agent and pass userToken for user isolation. DocSearch sends userToken when provided even if enabled is false.
A custom entry in askAi.tools with the same memory tool name replaces the built-in memory rendering.
See the JavaScript package reference or React package reference for the Memory configuration type.
Packages Website Docs Agent Studio Migrate To Agent Studio (`packages/website/docs/agent-studio/migrate-to-agent-studio.mdx`)
title: Migrate Ask AI to Agent Studio
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
Ask AI is now part of Agent Studio. Migrate your existing Ask AI assistant, publish the new agent, then point DocSearch at the agent ID.
DocSearch v5 uses Agent Studio as its only AI backend. There's no agentStudio flag.
If you're still on DocSearch v4, follow the v4 migration guide. To upgrade packages at the same time, see Migrate from DocSearch v4.
Migrate your assistant
1. Start the migration in the dashboard
- Sign in to the Algolia dashboard.
- Open Ask AI.
- Select your assistant and click Migrate to Agent Studio.
The wizard creates a draft Agent Studio agent from your assistant configuration, including the prompt, model, indices, and related settings. After migration, the assistant and agent are independent and don't stay in sync.
2. Review and publish the agent
- Open Agents in Agent Studio.
- Review the migrated agent.
- Publish the agent when you're ready to go live.
Copy the agent ID. DocSearch calls this value agentId in its public API.
3. Update your integration
Choose the path that matches how you embed Ask AI today:
Your existing Ask AI assistant keeps serving traffic until Ask AI is fully retired. Switch your client to the Agent Studio agent when you're ready.
Update DocSearch v5
Pass the Agent Studio agent ID as askAi.agentId, or as the askAi string shorthand. Rename any assistantId field to agentId.
Use DocSearchAI. Keyword-only DocSearch doesn't accept askAi.
import { DocSearchAI } from '@docsearch/react';
import '@docsearch/css';
export function Search() {
return (
<DocSearchAI
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_DOCSEARCH_INDEX']}
askAi={{
agentId: 'YOUR_AGENT_ID',
}}
/>
);
}The string shorthand remains supported:
<DocSearchAI
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['YOUR_DOCSEARCH_INDEX']}
askAi="YOUR_AGENT_ID"
/>Keep the root @docsearch/js import. It renders the AI-capable component:
import docsearch from '@docsearch/js';
import '@docsearch/css';
docsearch({
container: '#docsearch',
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_DOCSEARCH_INDEX'],
askAi: {
agentId: 'YOUR_AGENT_ID',
},
});Update `searchParameters`
Agent Studio search parameters are keyed by index name. Move any flat Ask AI searchParameters under the index:
askAi: {
- assistantId: 'YOUR_ASSISTANT_ID',
+ agentId: 'YOUR_AGENT_ID',
searchParameters: {
- filters: 'language:en',
- attributesToRetrieve: ['title', 'content', 'url'],
+ docs: {
+ filters: 'language:en',
+ attributesToRetrieve: ['title', 'content', 'url'],
+ },
},
}Supported keys are filters, attributesToRetrieve, restrictSearchableAttributes, and distinct. Don't put facetFilters in this object. Put fixed facet conditions in filters. For per-request index selection, see dynamic indices.
Docusaurus adapter
The adapter requires themeConfig.docsearch.askAi as an object with agentId. It rejects the string shorthand and the removed agentStudio property. See the Docusaurus adapter guide.
Custom Ask AI API integrations
If you call the Ask AI HTTP API yourself instead of using DocSearch, configure your client for Agent Studio instead of https://askai.algolia.com.
Don't build new integrations against the Ask AI chat API. Use the Agent Studio APIs:
- Integrate Agent Studio
- Agent Studio API
- Completions endpoint example:
https://{APPLICATION_ID}.algolia.net/agent-studio/1/agents/{AGENT_ID}/completions
Authenticate with your application ID and a search-only API key. Prefer the DocSearch configuration above when you embed DocSearch—the SDK wires the Agent Studio transport for you.
Next steps
After the agent ID is live in DocSearch:
Packages Website Docs Agent Studio Prompt Suggestions (`packages/website/docs/agent-studio/prompt-suggestions.mdx`)
title: Configure prompt suggestions
DocSearch v5 can show questions in three places. Each source has a different purpose and configuration.
- Suggested questions appear on the new-conversation screen. They come from published records for the agent in the fixed suggested-questions index. Configure them with
suggestedQuestions: true. - Keyword prompt suggestions appear while the user types in keyword search. They come from your Algolia prompt-suggestions index. Configure them with
promptSuggestions. - Streamed follow-ups appear below the latest completed answer. They come from
data-suggestionsstreamed by Agent Studio. Configure suggestions on the agent.
Show suggested questions
Enable curated starting questions with suggestedQuestions:
askAi: {
agentId: 'YOUR_AGENT_ID',
suggestedQuestions: true,
}DocSearch queries the algolia_ask_ai_suggested_questions index for records where state is published and assistantId matches the configured agent. It requests up to three records.
A suggested-question record has this shape, plus its Algolia objectID:
{
appId: string;
assistantId: string;
question: string;
locale?: string;
state: 'published';
source: string;
order: number;
}When a user selects one, DocSearch sends its objectID as suggestedQuestionId with the question.
Show prompt suggestions during keyword search
Create an Algolia index whose records contain a prompt string, then configure its name:
askAi: {
agentId: 'YOUR_AGENT_ID',
promptSuggestions: {
indexName: 'docs_prompt_suggestions',
hitsPerPage: 3,
},
}As the user types, DocSearch searches this index with the entered query and retrieves only the prompt attribute. It places matching prompts after the action that asks the entered text directly.
hitsPerPage defaults to 3. The Docusaurus adapter requires a positive value. If this search fails, DocSearch keeps the direct Ask AI action and omits the suggestions.
Selecting a prompt starts Agent Studio with that prompt. It doesn't send a suggestedQuestionId.
Show streamed follow-ups
Configure contextual suggestions in the Agent Studio agent editor. See write and configure agent prompts.
Agent Studio streams these follow-ups in a data-suggestions part. DocSearch renders its suggestions array below the latest answer only. Selecting one sends it as the next user message in the same conversation.
There's no DocSearch askAi option for streamed follow-ups. If Agent Studio doesn't stream data-suggestions, DocSearch doesn't show them.
See the JavaScript package reference and React package reference for the suggestion options and translation keys.
Packages Website Docs Agent Studio Tools (`packages/website/docs/agent-studio/tools.mdx`)
title: Add tools
Use tools to let your agent read live data or perform actions. Configure the tool and its input schema in Agent Studio, then add a matching entry to askAi.tools when DocSearch needs to run or render it.
See Agent Studio tools before exposing a tool to users.
Add a client-side tool
The key in tools must match the tool name configured in Agent Studio.
import { DocSearchAI, type ToolCalls } from '@docsearch/react';
const tools: ToolCalls = {
getAccountPlan: {
translations: {
callingToolText: 'Checking your account',
},
render({ message: { input, output } }) {
const result = output as { plan?: string } | undefined;
return result?.plan ? `Account plan: ${result.plan}` : '';
},
async onToolCall({ input, addToolOutput }) {
const response = await fetch('/api/account-plan', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(input),
});
const output = await response.json();
await addToolOutput({ output });
},
},
};
export function Search() {
return (
<DocSearchAI
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['docs']}
askAi={{
agentId: 'YOUR_AGENT_ID',
tools,
}}
/>
);
}The JavaScript package accepts the same askAi.tools object.
Every tool definition requires render. DocSearch calls it after output is available and passes both input and output. Return a string to show a result, or an empty string to show nothing.
Add onToolCall for a tool that runs in the browser. It receives:
input: the arguments selected by the agent. Treat this value as untrusted and validate it.toolCallId: the current call ID.toolName: the configured tool name.dynamic: whether the streamed call was marked as dynamic, when provided.addToolOutput: the function that returns the result to the conversation.
Call addToolOutput({ output }) after your work finishes. DocSearch invokes onToolCall without waiting for its returned promise, so handle failures inside the callback.
Keep browser tools within the signed-in user's permissions. Don't place service credentials in the tool definition. Call your backend for privileged work. See client-side tool security.
For React, define tools outside the component or memoize it. Recreating the object doesn't change behavior, but a stable object avoids rebuilding dependent configuration.
Render server-side or MCP tools
If Agent Studio executes a tool, omit onToolCall and provide render under the streamed tool name. DocSearch uses the output returned by Agent Studio.
const tools = {
get_release_status: {
render({ message: { output } }) {
const status = output?.status;
return status ? `Release status: ${status}` : '';
},
},
};Understand Algolia MCP search tools
DocSearch recognizes these Agent Studio search tool names without a tools entry:
algolia_search_index- Any name beginning with
algolia_search_index_
The recognized input includes query, index, optional number_of_results, and optional facet_filters. The output can include hits, nbHits, and queryId.
DocSearch shows search progress and the query used by the tool. It combines consecutive completed search calls into one search summary when more than one call has a nonempty query. A non-search message part ends the group.
You can add a matching tools entry to replace the built-in rendering for a search or memory tool. Your custom renderer takes precedence.
To connect other MCP servers to an agent, see MCP tools in Agent Studio. See the React package reference for ToolCalls and ToolDefinition.
Use tools with Docusaurus
Docusaurus removes functions while serializing theme configuration. The v5 adapter rejects askAi.tools and sidePanel.tools in docusaurus.config. Swizzle @theme/SearchBar and pass tools to the modal or Sidepanel from React instead.
See the Docusaurus adapter guide for the supported configuration.
Packages Website Docs Mcp Installation (`packages/website/docs/mcp/installation.mdx`)
title: Install DocSearch MCP sidebar_label: Installation
import MCPInstall from '@site/src/components/mcp/MCPInstall';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
DocSearch MCP is a remote MCP server. Point any MCP-compatible client at this endpoint — no authentication required:
https://mcp.algolia.com/1/docsearch/mcpThe fastest path to getting started is the DocSearch CLI — one command that configures your client for you. Prefer to set things up yourself? Install it as a plugin (ships the MCP server plus client guidance like rules, skills, and commands) or manually (just the MCP server config). Pick your client below.
Install a client plugin
Plugins include the MCP connection and instructions that teach the client when and how to use DocSearch.
Claude Code
Run these commands inside Claude Code:
/plugin marketplace add algolia/docsearch
/plugin install algolia-docsearch@algolia-docsearch-marketplaceThe plugin adds the MCP server, a skill, and the /algolia-docsearch:docs command.
Cursor
The Cursor plugin package is in the DocSearch repository at:
mcp/plugins/docsearch/cursor/algolia-docsearchIt includes the MCP server configuration, a rule, and a skill.
Configure a supported agent manually
Manual configuration adds the server but doesn't install the rules and skills supplied by the CLI or plugins.
Add this entry to ~/.cursor/mcp.json for user-level configuration or .cursor/mcp.json for project configuration:
{
"mcpServers": {
"algolia-docsearch": {
"url": "https://mcp.algolia.com/1/docsearch/mcp"
}
}
}Add the user-level remote server with the Claude Code CLI:
claude mcp add --scope user --transport http algolia-docsearch https://mcp.algolia.com/1/docsearch/mcpAdd the remote server with the Codex CLI:
codex mcp add algolia-docsearch --url https://mcp.algolia.com/1/docsearch/mcpYou can also add the URL under [mcp_servers.algolia-docsearch] in ~/.codex/config.toml.
Add this entry to opencode.json or opencode.jsonc:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"algolia-docsearch": {
"type": "remote",
"url": "https://mcp.algolia.com/1/docsearch/mcp",
"enabled": true
}
}
}Add this entry to .gemini/settings.json for project configuration or ~/.gemini/settings.json for user-level configuration:
{
"mcpServers": {
"algolia-docsearch": {
"httpUrl": "https://mcp.algolia.com/1/docsearch/mcp"
}
}
}Connect another MCP client
You can also connect clients that support remote HTTP MCP servers. Use these connection methods:
- Claude Desktop: Add a custom connector named
Algolia DocSearchwith the endpoint URL. - ChatGPT: Add a no-auth custom connector. Availability depends on the plan and workspace settings.
- Pi: Install an MCP extension or adapter before adding the server.
- VS Code: Add a remote server to the workspace or user MCP configuration. The tools are available in Copilot Chat agent mode.
- Windsurf: Add the endpoint to the Cascade MCP configuration, then restart Windsurf.
- Zed: Add the endpoint as a context server.
- Conductor: Configure the server in the selected Claude Code, Codex, or Cursor host. Conductor doesn't use a separate MCP configuration for those sessions.
- Antigravity: Add the endpoint through Manage MCP Servers > View raw config, then refresh the installed servers.
Configuration keys differ by client. Follow the client's MCP documentation and keep the server name algolia-docsearch and the endpoint URL unchanged.
Verify the installation
Ask your client to search public documentation:
Use DocSearch MCP to find the Next.js middleware matcher documentation.Confirm that the client calls a tool whose name starts with algolia_docsearch_ and returns source links from the selected documentation.
If verification fails, see Troubleshooting.
Packages Website Docs Mcp Usage (`packages/website/docs/mcp/usage.mdx`)
title: Use DocSearch MCP sidebar_label: Usage
Ask focused questions about public documentation. Include the official product name, topic, and version when the version affects the answer.
How do I configure middleware matchers in Next.js?Show me the Stripe webhook signature verification documentation.What is the setup for Algolia InstantSearch React?If your client doesn't select MCP tools on its own, name the server in your request:
Use DocSearch MCP to look up React Server Components data fetching.Ask the client to include source URLs when you need to inspect the supporting documentation.
Use the Claude Code command
The Claude Code plugin provides this command:
/algolia-docsearch:docs <library-or-product> [topic]For example:
/algolia-docsearch:docs Next.js middleware matcher
/algolia-docsearch:docs Stripe webhook signature verification
/algolia-docsearch:docs Algolia InstantSearch React configure search clientSearch from the terminal
@docsearch/cli can call the hosted MCP tools without a separate MCP client. Use docs for most questions:
docsearch docs Next.js "how do middleware matchers work"Limit the number of results or documentation sets when needed:
docsearch docs Next.js "cache revalidation" --max-results 3 --max-docsets 2For explicit documentation-set selection, resolve a product and then query its returned ID:
docsearch resolve "Algolia InstantSearch React"
docsearch query repo/algolia/instantsearch "configure the React search client"Limit resolver candidates with --top-n:
docsearch resolve Next.js --top-n 3Add --json to print the raw MCP result as JSON:
docsearch docs Next.js "cache revalidation" --jsonMachine-readable results go to standard output. Progress and errors go to standard error.
Choose a tool workflow
DocSearch MCP provides a one-shot search and a two-step search. Use natural-language questions rather than lists of keywords.
Search in one call
Use algolia_docsearch_search_docs for most questions. Keep the product name in library and the question in query:
{
"library": "Next.js",
"query": "how do middleware matchers work"
}The tool resolves the best documentation set and returns ranked content. If library doesn't identify a clear match, it returns candidate sets instead of searching the wrong one.
Resolve and query documentation sets
Use the two-step workflow when the product is ambiguous, you want to inspect the candidates, or the question covers multiple products.
Call
algolia_docsearch_resolve_docsetwith the product or platform name:json{ "query": "Next.js app router" }Select the best
docset_idfrom the response.Call
algolia_docsearch_query_docswith the selected ID and a focused question:json{ "query": "middleware matcher configuration", "docsetIds": ["nextjs"] }
Pass more than one docsetIds value when the question covers multiple products. Don't guess IDs. Use only IDs returned by algolia_docsearch_resolve_docset or algolia_docsearch_search_docs.
Troubleshooting
The client doesn't call DocSearch MCP
Confirm that the server is enabled and named algolia-docsearch. If you installed a plugin, confirm that the plugin is enabled. Then ask the client to use DocSearch MCP explicitly.
The client can't connect
Confirm that the client supports remote HTTP MCP servers and uses this exact HTTPS URL:
https://mcp.algolia.com/1/docsearch/mcpThe public endpoint doesn't require authentication. Remove application IDs, API keys, headers, or authentication settings that the client doesn't require.
CLI setup doesn't detect an agent
Pass the agent flag directly, or use --all with the setup command from the installation guide.
docsearch setup --project --cursor --yes
docsearch setup --global --all --yesSupported flags are --cursor, --claude, --codex, --opencode, and --gemini.
CLI setup reports an invalid configuration
Fix the reported JSON, JSONC, or TOML error before running setup again. The CLI stops instead of replacing an invalid configuration. It also rejects duplicate [mcp_servers.algolia-docsearch] sections in Codex configuration.
The result covers the wrong product
Use the official product or vendor name. For example, use Algolia InstantSearch instead of search. If the name remains ambiguous, resolve the documentation set first and query the selected ID.
The result is too broad or empty
Add the product version and narrow the question to one task. Run separate searches for unrelated topics. If a narrower search still returns no useful content, the requested documentation might not be in the public DocSearch corpus.
Private documentation isn't returned
DocSearch MCP searches public developer documentation only. It doesn't search private company docs, internal repositories, or unpublished APIs.
Packages Website Docs Packages Core Api (`packages/website/docs/packages/core/api.mdx`)
title: Core API reference toc_max_heading_level: 2
`DocSearch`
DocSearch is a ref-forwarding React provider.
`appId`
type: string| optional
Optional parent level application ID. If this is set, appId won't need to be set on the child Modal/Sidepanel.
`apiKey`
type: string| optional
Optional parent level search API key. If this is set, apiKey won't need to be set on the child Modal/Sidepanel.
`children`
type: React.ReactNode| required
Views and controls that consume DocSearch state.
`theme`
type: 'dark' | 'light'| optional
Sets document.documentElement.dataset.theme while mounted.
`initialQuery`
type: string| optional
Initial modal query and reset value after close. Defaults to ''.
`keyboardShortcuts`
type: KeyboardShortcuts| optional
Overrides individual shortcut defaults. All shortcuts are enabled by default.
`onReady`
type: () => void| optional
Runs after the provider mounts.
`onOpen`
type: () => void| optional
Runs when a modal opens.
`onClose`
type: () => void| optional
Runs when a modal closes to the ready state.
`onSidepanelOpen`
type: () => void| optional
Runs when the Sidepanel opens.
`onSidepanelClose`
type: () => void| optional
Runs when the Sidepanel closes.
`KeyboardShortcuts`
interface KeyboardShortcuts {
'Ctrl/Cmd+K'?: boolean;
'/'?: boolean;
'Ctrl/Cmd+I'?: boolean;
}DEFAULT_KEYBOARD_SHORTCUTS sets all three fields to true.
`DocSearchRef`
Attach this ref to DocSearch.
`open`
type: () => void
Opens the search modal.
`close`
type: () => void
Returns to the ready state and focuses the registered search button.
`openAskAi`
type: (message?: InitialAskAiMessage) => void
Opens Ask AI in a registered view. See Hybrid Mode.
`openSidepanel`
type: (message?: InitialAskAiMessage) => void
Opens the Sidepanel; it does nothing until that view registers.
`isReady`
type: readonly boolean
Whether the provider is mounted.
`isOpen`
type: readonly boolean
Whether a modal is open.
`isSidepanelOpen`
type: readonly boolean
Whether the Sidepanel is open.
`isSidepanelSupported`
type: readonly boolean
Whether Sidepanel support is registered. See Hybrid Mode.
type InitialAskAiMessage = {
query: string;
messageId?: string;
suggestedQuestionId?: string;
};`useDocSearch`
function useDocSearch(): DocSearchContext;The hook returns the nearest provider value.
DocSearchState is 'modal-askai' | 'modal-search' | 'ready' | 'sidepanel'.
View is 'modal' | 'sidepanel' | (Record<string, unknown> & string), so integrations can register another string view.
`docsearchState`
type: DocSearchState
Active state.
`setDocsearchState`
type: (state: DocSearchState) => void
Sets active state directly.
`searchButtonRef`
type: React.RefObject<HTMLButtonElement | null>
Ref used to restore focus after close.
`initialQuery`
type: string
Query for a modal opening.
`keyboardShortcuts`
type: Required<KeyboardShortcuts>
User options merged with defaults.
`openModal`
type: () => void
Opens keyword search.
`closeModal`
type: () => void
Closes the modal and resets its query.
`isAskAiActive`
type: boolean
Whether the modal is in Ask AI state.
`isModalActive`
type: boolean
Whether either modal state is active.
`onAskAiToggle`
type: OnAskAiToggle
Changes the active Ask AI state. See Hybrid Mode.
`initialAskAiMessage`
type: InitialAskAiMessage | undefined| optional
Initial Sidepanel message.
`registerView`
type: (view: View) => void
Registers an available view.
`isHybridModeSupported`
type: boolean
Whether cross-view support is available. See Hybrid Mode.
`useKeyboardShortcuts`
function useKeyboardShortcuts(
userShortcuts?: KeyboardShortcuts
): Required<KeyboardShortcuts>;Returns the defaults merged with the supplied fields.
`useTheme`
function useTheme(props: { theme?: 'dark' | 'light' }): void;When theme differs from the document's existing data-theme, the hook sets it and restores the previous value on cleanup. It makes no change when theme is omitted.
`useDocSearchKeyboardEvents`
interface UseDocSearchKeyboardEventsProps {
isOpen: boolean;
onOpen: () => void;
onClose: () => void;
isAskAiActive: boolean;
onAskAiToggle: (active: boolean) => void;
keyboardShortcuts?: KeyboardShortcuts;
onInput?: (event: KeyboardEvent) => void;
searchButtonRef?: React.RefObject<HTMLButtonElement | null>;
}The hook registers a window keydown listener. Escape leaves Ask AI first, then closes an open modal. Control/Command+K toggles the modal. / opens it when the user isn't editing content.
onInput and searchButtonRef remain in the type for compatibility but are deprecated and aren't used by the hook.
Exports
The root @docsearch/core entry exports:
| Kind | Exports |
|---|---|
| Components and hooks | DocSearch, useDocSearch, useDocSearchKeyboardEvents, useKeyboardShortcuts, useTheme |
| Constants | DEFAULT_KEYBOARD_SHORTCUTS |
| Types | DocSearchState, View, InitialAskAiMessage, OnAskAiToggle, DocSearchRef, DocSearchContext, DocSearchCallbacks, DocSearchProps, DocSearchTheme, UseThemeProps, UseDocSearchKeyboardEventsProps, DocSearchModalShortcuts, SidepanelShortcuts, KeyboardShortcuts |
The package also exposes these subpaths:
| Import path | Exports |
|---|---|
@docsearch/core/useDocSearchKeyboardEvents |
useDocSearchKeyboardEvents, UseDocSearchKeyboardEventsProps |
@docsearch/core/useKeyboardShortcuts |
useKeyboardShortcuts, DEFAULT_KEYBOARD_SHORTCUTS, shortcut types |
@docsearch/core/useTheme |
useTheme, DocSearchTheme, UseThemeProps |
useIsMobile is internal and isn't a package export.
Packages Website Docs Packages Css Bundle Exports (`packages/website/docs/packages/css/bundle-exports.mdx`)
title: CSS bundles and exports
@docsearch/css publishes compiled CSS and SCSS-named assets in dist. The package doesn't define an exports map, so import the root entry or a listed dist file.
Root entry
The package fields main, unpkg, and jsdelivr all point to dist/style.css.
These imports load the same full search-and-modal bundle:
import '@docsearch/css';
import '@docsearch/css/dist/style.css';Use only one of them.
Choose imports by surface
Each surface needs a different set of assets. See Published assets for the full file list.
Search button only
import '@docsearch/css/dist/button.css';Keyword-search modal
import '@docsearch/css/dist/button.css';
import '@docsearch/css/dist/modal.css';Use the root bundle instead if your modal can show Agent Studio responses.
Agent Studio modal
import '@docsearch/css';Sidepanel
import '@docsearch/css';
import '@docsearch/css/dist/sidepanel.css';The Sidepanel reuses Agent Studio response and Markdown classes from the root bundle, so sidepanel.css isn't the complete Sidepanel presentation by itself.
Load from a CDN
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@docsearch/css@^5/dist/style.css"
/>Add the Sidepanel asset when needed:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@docsearch/css@^5/dist/sidepanel.css"
/>Use the caret beta range so compatible beta updates remain available.
Published assets
| Path | Contents |
|---|---|
@docsearch/css/dist/style.css |
Variables, search button, modal, and Agent Studio response styles. |
@docsearch/css/dist/_variables.css |
Shared light and dark custom properties. |
@docsearch/css/dist/button.css |
Variables and search-button styles. |
@docsearch/css/dist/modal.css |
Variables and keyword-search modal styles. |
@docsearch/css/dist/_askai.css |
Agent Studio modal response and Markdown styles. |
@docsearch/css/dist/sidepanel.css |
Variables, Sidepanel button, panel layout, and Sidepanel-specific overrides. |
Each asset also has an equivalent .scss file: style.scss, _variables.scss, button.scss, modal.scss, _askai.scss, and sidepanel.scss. The build writes the compiled bundle to both extensions; these aren't Sass source partials.
React style bridge exports
@docsearch/react v5 beta also exposes JavaScript style bridge entry points. They re-export files from @docsearch/css:
| Import path | CSS target |
|---|---|
@docsearch/react/style |
@docsearch/css |
@docsearch/react/style/variables |
@docsearch/css/dist/_variables.css |
@docsearch/react/style/button |
@docsearch/css/dist/button.css |
@docsearch/react/style/modal |
@docsearch/css/dist/modal.css |
@docsearch/react/style/askai |
@docsearch/css/dist/_askai.css |
@docsearch/react/style/sidepanel |
@docsearch/css/dist/sidepanel.css |
Prefer direct @docsearch/css imports when your bundler supports CSS package imports. They show which assets enter your bundle and work across the DocSearch React packages.
Packages Website Docs Packages Css Styling (`packages/website/docs/packages/css/styling.mdx`)
title: Style DocSearch
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';
@docsearch/css contains the styles for the search button, modal, and Sidepanel.
Install and import
npm install @docsearch/css@^5yarn add @docsearch/css@^5pnpm add @docsearch/css@^5bun add @docsearch/css@^5For the search button and modal, import the package root:
import '@docsearch/css';The root stylesheet includes variables, button styles, modal styles, and Agent Studio response styles. It doesn't include Sidepanel layout styles.
For a Sidepanel, add its stylesheet after the root stylesheet:
import '@docsearch/css';
import '@docsearch/css/dist/sidepanel.css';Override variables
Load your overrides after DocSearch CSS.
:root {
--docsearch-primary-color: #2457d6;
--docsearch-primary-dark-color: #173b99;
--docsearch-focus-color: #0b57d0;
--docsearch-modal-width: 48rem;
--docsearch-modal-radius: 0.75rem;
--docsearch-hit-height: 3.75rem;
--docsearch-border-radius: 0.375rem;
}Prefer variables over selector overrides. Variables preserve focus, responsive, and state styles across package updates.
Frequently used variables include:
- Brand and state:
--docsearch-primary-color,--docsearch-primary-dark-color,--docsearch-highlight-color,--docsearch-focus-color,--docsearch-error-color,--docsearch-success-color - Text and surfaces:
--docsearch-text-color,--docsearch-secondary-text-color,--docsearch-background-color,--docsearch-modal-background,--docsearch-subtle-color,--docsearch-muted-color - Modal:
--docsearch-modal-width,--docsearch-modal-height,--docsearch-modal-variable-height,--docsearch-modal-radius,--docsearch-modal-shadow - Search box and hits:
--docsearch-searchbox-height,--docsearch-searchbox-background,--docsearch-hit-height,--docsearch-hit-background,--docsearch-hit-focus-background - Button:
--docsearch-search-button-background,--docsearch-search-button-text-color - Sidepanel:
--docsearch-sidepanel-background,--docsearch-sidepanel-primary,--docsearch-sidepanel-border,--docsearch-sidepanel-text-base,--docsearch-sidepanel-text-muted
Set dark theme values
DocSearch applies dark variables under html[data-theme='dark']. The theme="dark" prop on a DocSearch component sets this attribute.
Override dark values with the same selector:
html[data-theme='dark'] {
--docsearch-modal-background: #111827;
--docsearch-background-color: #1f2937;
--docsearch-text-color: #f3f4f6;
--docsearch-secondary-text-color: #d1d5db;
--docsearch-hit-background: #111827;
--docsearch-hit-focus-background: #263244;
}Add targeted overrides
All component classes use the DocSearch- prefix. Scope selector overrides to a component and preserve visible focus states.
.DocSearch-Button {
min-width: 15rem;
}
.DocSearch-Sidepanel-Container.floating {
box-shadow: 0 1rem 3rem rgb(0 0 0 / 20%);
}
.DocSearch-Action:focus-visible,
.DocSearch-Button:focus-visible {
outline: 2px solid var(--docsearch-focus-color);
outline-offset: 2px;
}Don't remove the visually hidden helpers or reduced-motion rules. They support accessible labels, keyboard use, and user motion preferences.
See the CSS bundle and export guide when you need component-specific assets.
Packages Website Docs Packages Docusaurus Adapter Configuration Reference (`packages/website/docs/packages/docusaurus-adapter/configuration-reference.mdx`)
title: Docusaurus adapter configuration toc_max_heading_level: 2
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Add supported options under themeConfig.docsearch. The adapter doesn't read themeConfig.algolia.
export default {
plugins: ['@docsearch/docusaurus-adapter'],
themeConfig: {
docsearch: {
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: ['YOUR_INDEX_NAME'],
},
},
};Compatibility
| Dependency | Supported version |
|---|---|
| Node.js | 20 or later |
| Docusaurus | 3.10.2 or later in the 3.x release line |
| React and React DOM | 18 or 19 |
Keep the adapter, Docusaurus, React, and React DOM within these ranges. Don't run the adapter beside @docusaurus/theme-search-algolia.
Root options
The validator rejects unknown root options. Pass runtime functions such as custom Agent Studio tools through a swizzled SearchBar instead of themeConfig.
`appId`
type: string| required
Algolia application ID.
`apiKey`
type: string| required
Public API key with search permission.
`indices`
type: Array<string | DocSearchIndex>| required
Nonempty list of keyword indices, in query order. See Indices and search parameters.
`contextualSearch`
type: boolean| optional
Whether to add the current Docusaurus locale, default tag, and docs-version tags to search. Defaults to true. See Contextual search.
`externalUrlRegex`
type: string| optional
Regular expression that identifies result URLs that require full-page navigation. See URL processing.
`replaceSearchResultPathname`
type: { from: string | RegExp, to: string }| optional
Replace a result pathname before adding the Docusaurus base URL. See URL processing.
`facets`
type: Array<{ key: string, label?: string }>| optional
Facet controls in the search modal. Defaults to []. See Modal facets.
`initialQuery`
type: string| optional
Query placed in the modal when it opens. Defaults to ''.
`insights`
type: boolean | object| optional
Whether to enable Algolia Insights, or an object that configures it. Defaults to false.
`placeholder`
type: string| optional
Search input placeholder. Defaults to the built-in translation.
`translations`
type: DocSearchTranslations| optional
Search button and modal text overrides. Defaults to the Docusaurus translations.
`maxResultsPerGroup`
type: number| optional
Maximum results shown in each modal result group.
`disableUserPersonalization`
type: boolean| optional
Whether to disable recent searches, favorites, and stored AI conversations. Defaults to false.
`getMissingResultsUrl`
type: ({ query }) => string| optional
Build the no-results report URL.
`keyboardShortcuts`
type: object| optional
Enable or disable Ctrl/Cmd+K, /, and Ctrl/Cmd+I. All shortcuts are enabled by default.
`recentSearchesLimit`
type: number| optional
Maximum recent searches when no favorites exist. Defaults to 7.
`recentSearchesWithFavoritesLimit`
type: number| optional
Maximum recent searches when favorites exist. Defaults to 4.
`resultBadgeKey`
type: string| optional
Hit property rendered as a badge in modal results. See Result badges.
`searchPage`
type: false | SearchPageConfig| optional
Configure or disable the search results page. Defaults to { path: 'search' }. See Search page.
`askAi`
type: AskAiConfig| optional
Configure Agent Studio for the modal and Sidepanel. See Ask AI.
`sidePanel`
type: boolean | SidePanelConfig| optional
Whether to enable the Ask AI Sidepanel, or an object that configures it. Defaults to false. See Sidepanel.
Indices and search parameters
Define at least one keyword index. Use a string for its default settings or an object for per-index settings:
indices: [
'docs_en',
{
name: 'api_reference',
searchParameters: {
facetFilters: ['version:v5'],
filters: 'visibility:public',
attributesToRetrieve: [
'content',
'hierarchy',
'type',
'url',
'version',
],
restrictSearchableAttributes: ['hierarchy', 'content'],
distinct: true,
},
},
],searchParameters accepts Algolia search parameters. The validator explicitly accepts facetFilters, filters, attributesToRetrieve, restrictSearchableAttributes, and distinct, and preserves other Algolia parameters.
The modal queries every index in array order. The search page queries only the first index.
Contextual search
Keep contextualSearch: true to limit results to the current locale and Docusaurus docs versions. The adapter merges these conditions into each index's facetFilters instead of replacing your filters.
Contextual search also applies to Ask AI when you set askAi.indices. The adapter merges version and language filters into askAi.searchParameters[index].filters for each dynamic index name.
Set contextualSearch: false when your records don't contain Docusaurus language and docusaurus_tag attributes:
docsearch: {
// ...
contextualSearch: false,
},Modal facets
Use root facets to add filter controls to the modal:
docsearch: {
// ...
facets: [
{ key: 'language', label: 'Language' },
{ key: 'version', label: 'Version' },
],
},Configure each attribute as an Algolia facet. The modal supports up to five unique, nonempty facet keys. It merges facet values from every keyword index and hides facets with no values.
Users can select multiple values per facet. The modal combines values of the same facet with OR and different facets with AND. When contextualSearch is on, the modal uses the contextual filters as initial selections. Expose language to let users change the current locale filter, or docusaurus_tag to let users change the default and docs version tags.
These controls don't configure the search page sidebar. Use searchPage.facets for that page.
Result badges
Set resultBadgeKey to a property path returned by each keyword index:
docsearch: {
// ...
indices: [
{
name: 'docs',
searchParameters: {
attributesToRetrieve: [
'content',
'hierarchy',
'type',
'url',
'version',
],
},
},
],
resultBadgeKey: 'version',
},Dot paths and array indices work, including hierarchy.lvl1, tags[2], and tags.2. The adapter displays the badge in modal results. The built-in search page doesn't render result badges.
Search page
The adapter creates /search by default. Change the path and sidebar facets with an object:
searchPage: {
path: 'find',
facets: [
{ attribute: 'hierarchy.lvl0', label: 'Section' },
{ attribute: 'version', label: 'Version' },
],
},Each facet requires attribute; label defaults to the attribute name. If facets is missing or empty, the page shows hierarchy.lvl0 with the label Section.
The page uses the first indices item and its searchParameters. It shows 15 results per request, stores refinements in the URL, and adds docs-version controls when contextual search and Docusaurus versioning are active. Configure every sidebar attribute as an Algolia facet.
Disable the route, modal footer link, and OpenSearch metadata with:
searchPage: false,Ask AI
Create an assistant by following Get started with Agent Studio. Set askAi to an object:
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
suggestedQuestions: true,
searchParameters: {
docs: {
filters: 'visibility:public',
attributesToRetrieve: ['title', 'content', 'url'],
distinct: true,
},
},
memory: {
enabled: true,
userToken: 'SERVER_GENERATED_JWT',
},
promptSuggestions: {
indexName: 'docs_prompt_suggestions',
hitsPerPage: 3,
},
},`assistantId`
type: string| required
Agent Studio assistant ID.
`suggestedQuestions`
type: boolean| optional
Whether to show published assistant questions on the new-conversation screen. Defaults to false.
`searchParameters`
type: Record<string, AgentStudioSearchParameters>| optional
Search parameters keyed by index name. Root askAi.searchParameters supports filters, attributesToRetrieve, restrictSearchableAttributes, and distinct. Don't add facetFilters at this level.
`indices`
type: string[]| optional
Index names available to Agent Studio search tools. See dynamic indices.
askAi: {
agentId: 'YOUR_ASSISTANT_ID',
indices: ['docs_markdown'],
searchParameters: {
docs_markdown: {
filters: 'language:en',
},
},
},`memory`
type: { enabled?: boolean, userToken?: string }| optional
Show memory tool calls and send a user JWT. Memory is disabled by default. See user-scoped memory.
`promptSuggestions`
type: { indexName: string, hitsPerPage?: number }| optional
Show prompt suggestions with keyword results. hitsPerPage defaults to 3. See Configure prompt suggestions.
Sidepanel
Set sidePanel: true for the default panel. askAi is required whenever the Sidepanel is enabled.
sidePanel: {
variant: 'inline',
side: 'right',
width: 420,
expandedWidth: '60vw',
pushSelector: '#__docusaurus',
suggestedQuestions: true,
hideButton: false,
keyboardShortcuts: {
'Ctrl/Cmd+I': true,
},
},Review hybrid mode before changing panel behavior.
`variant`
type: 'floating' | 'inline'| optional
Float above content or push selected content. Defaults to 'inline'.
`side`
type: 'left' | 'right'| optional
Side where the panel opens. Defaults to 'right'.
`width`
type: number | string| optional
Collapsed panel width. Numbers represent pixels. Defaults to 360px.
`expandedWidth`
type: number | string| optional
Expanded panel width. Numbers represent pixels. Defaults to 580px.
`pushSelector`
type: string| optional
Element pushed by the inline panel. Defaults to #__docusaurus.
`suggestedQuestions`
type: boolean| optional
Whether to show suggested questions in the panel. Defaults to askAi.suggestedQuestions.
`translations`
type: SidepanelTranslations| optional
Panel text overrides. Defaults to the built-in strings.
`hideButton`
type: boolean| optional
Whether to hide the Sidepanel button while keeping the panel registered. Defaults to false.
`portalContainer`
type: DocumentFragment | Element | null| optional
Element that receives the panel portal. Defaults to document.body. Pass this option through a swizzled SearchBar because a DOM element isn't available while Docusaurus evaluates its server configuration.
`keyboardShortcuts`
type: { 'Ctrl/Cmd+I'?: boolean }| optional
Enable or disable the panel shortcut. The shortcut is enabled by default.
`indices`
type: string[]| optional
Override Agent Studio indices for the panel. Defaults to askAi.indices. See dynamic indices.
`memory`
type: { enabled?: boolean, userToken?: string }| optional
Override memory for the panel. Defaults to askAi.memory. See user-scoped memory.
Custom tools
Docusaurus can't serialize tool functions in themeConfig. The adapter rejects both askAi.tools and sidePanel.tools there.
Swizzle SearchBar from @docsearch/docusaurus-adapter, then pass tools as component props:
npm run swizzle -- @docsearch/docusaurus-adapter SearchBar --ejectReplace the generated component with one of these examples:
import type { DocusaurusSearchBarProps } from '@docsearch/docusaurus-adapter';
import type { ToolCalls } from '@docsearch/react';
import OriginalSearchBar from '@theme-original/SearchBar';
const tools: ToolCalls = {
getReleaseStatus: {
render: ({ message }) => JSON.stringify(message.output),
},
};
export default function SearchBar(props: DocusaurusSearchBarProps) {
return (
<OriginalSearchBar
{...props}
askAi={{
assistantId: 'YOUR_ASSISTANT_ID',
tools,
}}
sidePanel={{ tools }}
/>
);
}import OriginalSearchBar from '@theme-original/SearchBar';
const tools = {
getReleaseStatus: {
render: ({ message }) => JSON.stringify(message.output),
},
};
export default function SearchBar(props) {
return (
<OriginalSearchBar
{...props}
askAi={{
assistantId: 'YOUR_ASSISTANT_ID',
tools,
}}
sidePanel={{ tools }}
/>
);
}Passing askAi or sidePanel as a prop replaces that nested theme-config value. Include every nested option that you want to keep in the prop object. See Agent Studio tools for tool renderers and client-side handlers.
Translations
Override only the modal strings you need:
translations: {
button: {
buttonText: 'Search API docs',
buttonAriaLabel: 'Search API docs',
},
modal: {
searchBox: {
placeholderText: 'Search API docs',
},
facets: {
clearAllLabel: 'Reset filters',
},
resultsScreen: {
resultBadgeLabelText: 'Version',
},
},
},The adapter uses Docusaurus translation IDs for its default search button, modal, and search page strings. Run the Docusaurus write-translations command to localize built-in strings. Put Sidepanel overrides under sidePanel.translations.
URL processing
The adapter parses each result URL. It leaves URLs matching externalUrlRegex unchanged and uses full-page navigation for them. For other URLs, it keeps the pathname, query, and hash, applies replaceSearchResultPathname, and adds the Docusaurus base URL.
docsearch: {
// ...
externalUrlRegex: '^https://external\\.example\\.com/',
replaceSearchResultPathname: {
from: '/legacy-docs/',
to: '/docs/',
},
},A string from value is treated literally. A RegExp is converted to its source during validation.
Validation errors
The adapter reports dedicated errors for removed or unsupported v4 options. Use the replacement named in each message:
`themeConfig.algolia` is no longer supported by @docsearch/docusaurus-adapter v5. Move the configuration to `themeConfig.docsearch`.
`themeConfig.docsearch.indexName` was removed. Use `themeConfig.docsearch.indices` instead.
`themeConfig.docsearch.searchParameters` was removed. Configure `searchParameters` on each `themeConfig.docsearch.indices` entry instead.
`themeConfig.docsearch.searchPagePath` was removed. Use `themeConfig.docsearch.searchPage` instead.
`themeConfig.docsearch.askAi` must be an object with `assistantId`.
`themeConfig.docsearch.askAi.agentStudio` was removed. The adapter now only supports Agent Studio.
`themeConfig.docsearch.askAi.indexName`, `apiKey`, and `appId` were removed. Use the top-level DocSearch credentials instead.
`themeConfig.docsearch.askAi.sidePanel` was removed. Use `themeConfig.docsearch.sidePanel` instead.
`themeConfig.docsearch.sidePanel` requires `themeConfig.docsearch.askAi`.Tool definitions report these errors:
`themeConfig.docsearch.askAi.tools` is not supported because Docusaurus removes function values when serializing theme config. Pass custom tools through a swizzled `@theme/SearchBar` component instead: use `askAi` for the modal and `sidePanel` for the side panel.
`themeConfig.docsearch.sidePanel.tools` is not supported because Docusaurus removes function values when serializing theme config. Pass custom tools through a swizzled `@theme/SearchBar` component instead: use `askAi` for the modal and `sidePanel` for the side panel.The schema also reports these messages for missing or invalid required configuration:
"themeConfig.docsearch" is required
"docsearch.appId" is required. If you haven't migrated to the new DocSearch infra, please refer to the blog post for instructions: https://docusaurus.io/blog/2021/11/21/algolia-docsearch-migration
"docsearch.apiKey" is required
"docsearch.indices" is required
"docsearch.indices" must contain at least 1 items
"docsearch.unknownKey" is not allowed
"docsearch.askAi.indices" must contain at least 1 items
"docsearch.askAi.indices[0]" must be a string
"docsearch.sidePanel.indices" must contain at least 1 items
"docsearch.sidePanel.indices[0]" must be a stringReplace unknownKey with the rejected option name. Other invalid nested values use the same Joi path format.
Packages Website Docs Packages Docusaurus Adapter Migrating From V4 (`packages/website/docs/packages/docusaurus-adapter/migrating-from-v4.mdx`)
title: Migrate the Docusaurus adapter from v4
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
DocSearch v5 requires themeConfig.docsearch, a nonempty indices array, and Agent Studio for Ask AI. Update the adapter and configuration together.
Review the broader DocSearch v4 migration guide for changes outside the Docusaurus adapter.
1. Check compatibility
Upgrade the site to Node.js 20 or later and Docusaurus 3.10.2 or later in the Docusaurus 3 release line. Use React and React DOM 18 or 19.
2. Install the v5 adapter
Install @docsearch/docusaurus-adapter@^5:
npm install @docsearch/docusaurus-adapter@^5yarn add @docsearch/docusaurus-adapter@^5pnpm add @docsearch/docusaurus-adapter@^5bun add @docsearch/docusaurus-adapter@^5Keep the adapter in plugins and don't add @docusaurus/theme-search-algolia as another search integration.
3. Move to `themeConfig.docsearch`
V4 accepted themeConfig.algolia as an alias. V5 rejects it.
export default {
plugins: ['@docsearch/docusaurus-adapter'],
themeConfig: {
algolia: {
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indexName: 'docs',
},
},
};export default {
plugins: ['@docsearch/docusaurus-adapter'],
themeConfig: {
docsearch: {
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: [{ name: 'docs' }],
},
},
};Don't define both keys during the migration. V5 accepts only themeConfig.docsearch.
4. Replace `indexName` and root search parameters
Move every keyword index into indices. Move root searchParameters onto the matching index:
docsearch: {
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indexName: 'docs',
searchParameters: {
facetFilters: ['language:en'],
attributesToRetrieve: ['content', 'hierarchy', 'type', 'url'],
},
},docsearch: {
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indices: [
{
name: 'docs',
searchParameters: {
facetFilters: ['language:en'],
attributesToRetrieve: ['content', 'hierarchy', 'type', 'url'],
},
},
],
},indices is required and must contain at least one item. The modal queries all items in order. The search page uses the first item.
5. Replace `searchPagePath`
V5 replaces the path value with an object that can also configure facets:
searchPagePath: 'find',searchPage: {
path: 'find',
facets: [
{ attribute: 'hierarchy.lvl0', label: 'Section' },
{ attribute: 'version', label: 'Version' },
],
},Use searchPage: false to disable the route. An empty object uses the default search path and the default hierarchy.lvl0 section facet.
6. Move Ask AI to Agent Studio
Create an assistant by following Get started with Agent Studio. V5 accepts only an askAi object and always uses Agent Studio.
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
appId: 'ASK_AI_APPLICATION_ID',
apiKey: 'ASK_AI_SEARCH_API_KEY',
indexName: 'docs_markdown',
agentStudio: true,
},V4 also accepted this shorthand:
askAi: 'YOUR_ASSISTANT_ID',askAi: {
agentId: 'YOUR_ASSISTANT_ID',
indices: ['docs_markdown'],
},Remove agentStudio, appId, apiKey, and indexName from askAi. The adapter reuses the root credentials. Without askAi.indices, it uses the first keyword index as the Ask AI index.
V4 supported flat search parameters for the legacy Ask AI backend. V5 requires Agent Studio search parameters keyed by index name:
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
searchParameters: {
filters: 'language:en',
attributesToRetrieve: ['title', 'content', 'url'],
},
},askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
searchParameters: {
docs: {
filters: 'language:en',
attributesToRetrieve: ['title', 'content', 'url'],
},
},
},Root askAi.searchParameters supports filters, attributesToRetrieve, restrictSearchableAttributes, and distinct.
7. Move the Sidepanel to the root
Move sidePanel out of askAi:
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
sidePanel: {
variant: 'inline',
side: 'right',
},
},askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
},
sidePanel: {
variant: 'inline',
side: 'right',
},The root sidePanel requires askAi. It can override Agent Studio indices, memory, suggestedQuestions, and translations for the panel. Review hybrid mode for modal and panel behavior.
8. Move custom tools into `SearchBar`
V5 rejects askAi.tools and sidePanel.tools in docusaurus.config because Docusaurus removes functions while serializing theme config. Swizzle @theme/SearchBar and pass tools as component props.
npm run swizzle -- @docsearch/docusaurus-adapter SearchBar --ejectimport type { DocusaurusSearchBarProps } from '@docsearch/docusaurus-adapter';
import type { ToolCalls } from '@docsearch/react';
import OriginalSearchBar from '@theme-original/SearchBar';
const tools: ToolCalls = {
getReleaseStatus: {
render: ({ message }) => JSON.stringify(message.output),
},
};
export default function SearchBar(props: DocusaurusSearchBarProps) {
return (
<OriginalSearchBar
{...props}
askAi={{ assistantId: 'YOUR_ASSISTANT_ID', tools }}
sidePanel={{ tools }}
/>
);
}import OriginalSearchBar from '@theme-original/SearchBar';
const tools = {
getReleaseStatus: {
render: ({ message }) => JSON.stringify(message.output),
},
};
export default function SearchBar(props) {
return (
<OriginalSearchBar
{...props}
askAi={{ assistantId: 'YOUR_ASSISTANT_ID', tools }}
sidePanel={{ tools }}
/>
);
}Include every nested askAi and sidePanel option that you want to keep because component props replace those nested theme-config values. See Agent Studio tools for complete tool definitions.
9. Add v5 search features
Configure modal facets at the docsearch root:
facets: [
{ key: 'language', label: 'Language' },
{ key: 'version', label: 'Version' },
],Configure search-page facets separately under searchPage.facets. Configure every facet attribute in your Algolia index.
Show a custom hit property in modal results with resultBadgeKey. Add that property to each index's attributesToRetrieve:
indices: [
{
name: 'docs',
searchParameters: {
attributesToRetrieve: [
'content',
'hierarchy',
'type',
'url',
'version',
],
},
},
],
resultBadgeKey: 'version',10. Verify the migration
Run the production Docusaurus build, then verify these paths:
- Open keyword search with the button,
Ctrl/Cmd+K, and/. - Search every configured index and apply each modal facet.
- Open the search page, apply its facets, and check docs-version filtering.
- Open Ask AI and submit a follow-up question.
- Open the Sidepanel with its button and
Ctrl/Cmd+I. - Check contextual results in every locale and docs version.
- Follow internal, replaced, and external result URLs.
- Check translated strings and result badges.
- Test mobile behavior. Hybrid mode uses the modal instead of the Sidepanel on mobile.
Use the configuration reference to resolve validation messages and review every v5 option.
Packages Website Docs Packages Js Api Reference (`packages/website/docs/packages/js/api-reference.mdx`)
title: JS package API reference toc_max_heading_level: 2
`docsearch(options)`
Renders DocSearch in options.container and returns a DocSearchInstance.
import docsearch from '@docsearch/js';
const instance = docsearch(options);The default export from @docsearch/js is AI-capable and uses DocSearchAI. The default export from @docsearch/js/docsearch is keyword-only and uses DocSearch.
JavaScript options
`container`
type: HTMLElement | string| required
Container element or CSS selector for the search button. A selector resolves against environment.document and must match an element.
`environment`
type: typeof window| optional
Browser-like environment used to resolve a string container. Defaults to window.
`onReady`
type: () => void| optional
Callback after DocSearch mounts.
`onOpen`
type: () => void| optional
Callback when the modal opens.
`onClose`
type: () => void| optional
Callback when the modal closes.
`interceptAskAiEvent`
type: (initialMessage: InitialAskAiMessage) => boolean | void| optional
Callback before DocSearch starts an Ask AI request. Return true to prevent the modal from toggling or sending the message. Use this option to route the request to another view, such as the Sidepanel.
InitialAskAiMessage contains query and can contain messageId or suggestedQuestionId.
Search options
These options apply to both package entries.
`appId`
type: string| required
Algolia application ID.
`apiKey`
type: string| required
Public API key with search permission.
`indices`
type: Array<string | DocSearchIndex>| optional
Indices used for keyword search, in display order. There's no default, and at least indices or indexName is required.
Use a string for default search parameters or a DocSearchIndex for per-index parameters:
interface DocSearchIndex {
name: string;
searchParameters?: SearchParamsObject;
}indices: [
{
name: 'docs_en',
searchParameters: {
facetFilters: ['version:v5'],
attributesToRetrieve: [
'hierarchy.lvl0',
'hierarchy.lvl1',
'hierarchy.lvl2',
'hierarchy.lvl3',
'hierarchy.lvl4',
'hierarchy.lvl5',
'hierarchy.lvl6',
'content',
'type',
'url',
'version',
],
},
},
'docs_fr',
];If you pass both indexName and indices, DocSearch queries indexName first, then each indices item. indexName and the root searchParameters remain available for v4 compatibility but are deprecated.
`indexName`
type: string| optional
Deprecated index name. There's no default. Use indices.
`facets`
type: DocSearchFacet[]| optional
Facet controls populated from the configured indices. Defaults to [].
interface DocSearchFacet {
key: string;
label?: string;
}DocSearch supports up to five facets. It compares trimmed, lowercase keys to ignore duplicates and empty keys, fetches values from all configured indices, and displays only facets that have values.
Users can select multiple values per facet. DocSearch combines values of the same facet with OR and different facets with AND when it builds facetFilters for each index. A selection replaces the index's configured facetFilters entries for that facet key and keeps entries for other keys. DocSearch also replaces a configured OR group when the user has a selection for every key in the group.
facets: [
{ key: 'language', label: 'Language' },
{ key: 'version', label: 'Version' },
];Configure each attribute for faceting in the Algolia index before exposing it here.
`theme`
type: 'light' | 'dark'| optional
Theme written to document.documentElement.dataset.theme. By default, DocSearch leaves the current theme unchanged.
`placeholder`
type: string| optional
Search input placeholder. The default is experience-specific.
`searchParameters`
type: SearchParamsObject| optional
Deprecated search parameters for indexName. There's no default. Put them on an indices item.
`maxResultsPerGroup`
type: number| optional
Maximum results in each result group. There's no default.
`transformItems`
type: (items: DocSearchHit[]) => DocSearchHit[]| optional
Function that transforms hits before grouping and rendering. Defaults to the identity function.
`hitComponent`
type: ({ hit, children }, { html }) => JSX.Element| optional
Template for a result link. Defaults to the built-in hit template. See Templates.
`resultsFooterComponent`
type: ({ state }, { html }) => JSX.Element | null| optional
Template below the result collections. There's no default. See Templates.
`footerAction`
type: (_, { html }) => JSX.Element | null| optional
Optional function to render a custom action in the Modal's footer. It will be rendered in line with the Algolia "powered by" logo. See Templates.
`transformSearchClient`
type: (client) => client| optional
Function that wraps or replaces the Algolia search client. Defaults to the identity function.
`disableUserPersonalization`
type: boolean| optional
Whether to disable recent searches, favorites, and stored AI conversations. Defaults to false.
`initialQuery`
type: string| optional
Query placed in the input when the modal opens. Defaults to ''.
`navigator`
type: AutocompleteOptions['navigator']| optional
Autocomplete navigation implementation. Defaults to the default navigator.
`translations`
type: DocSearchTranslations| optional
Button and modal text overrides. Defaults to the English strings.
`getMissingResultsUrl`
type: ({ query }) => string| optional
Function that builds the no-results report URL. There's no default.
`insights`
type: AutocompleteOptions['insights']| optional
Algolia Insights integration options. Defaults to false.
`portalContainer`
type: DocumentFragment | Element| optional
Element that receives the modal portal. Defaults to document.body.
`recentSearchesLimit`
type: number| optional
Maximum recent searches without favorites. Defaults to 7.
`recentSearchesWithFavoritesLimit`
type: number| optional
Maximum recent searches when favorites exist. Defaults to 4.
`keyboardShortcuts`
type: DocSearchModalShortcuts| optional
Whether Ctrl/Cmd+K and / open the modal. Both shortcuts are enabled by default. Escape always closes it.
`resultBadgeKey`
type: string| optional
Hit property rendered as a result badge. There's no default.
The key supports property paths such as version, hierarchy.lvl1, tags[2], and tags.2. Primitive values render as text. Arrays of primitive values render as a comma-separated list.
Add custom badge data to attributesToRetrieve. Otherwise the property isn't present in the hit:
indices: [
{
name: 'docs',
searchParameters: {
attributesToRetrieve: [
'hierarchy.lvl0',
'hierarchy.lvl1',
'hierarchy.lvl2',
'hierarchy.lvl3',
'hierarchy.lvl4',
'hierarchy.lvl5',
'hierarchy.lvl6',
'content',
'type',
'url',
'version',
],
},
},
],
resultBadgeKey: 'version',Set translations.modal.resultsScreen.resultBadgeLabelText to describe the badge to screen-reader users. Its default is Category.
Templates
hitComponentreceives{ hit, children }.resultsFooterComponentreceives{ state }.footerActioncurrently does not receive any extra props.
JavaScript templates can return a Preact element, a string, or a component function. The optional second argument provides an html tagged-template helper.
docsearch({
hitComponent({ hit, children }, { html }) {
return html`<a href=${hit.url} data-result-type=${hit.type}>${children}</a>`;
},
resultsFooterComponent({ state }, { html }) {
return html`<p>No results found for query: ${state.query}</p>`;
},
footerAction(_, { html }) {
return html`<a href="https://algolia.com">Our other project</a>`;
},
});Ask AI options
Ask AI is available from the default @docsearch/js entry. Its askAi option is required by that entry's DocSearchProps type.
`askAi`
type: string | DocSearchAskAi| required
Assistant ID or Agent Studio configuration. The default entry requires it.
askAi: 'YOUR_ASSISTANT_ID';Use an object for additional controls.
Follow Get started with Agent Studio to create the assistant and hybrid mode to route AI requests to a Sidepanel.
`assistantId`
type: string| required
Agent Studio assistant ID.
`appId`
type: string| optional
Application ID used by Ask AI. Defaults to the root appId.
`apiKey`
type: string| optional
API key used by Ask AI. Defaults to the root apiKey.
`indexName`
type: string| optional
Index used by Ask AI. Defaults to the first normalized keyword index.
`suggestedQuestions`
type: boolean| optional
Whether to show published assistant questions on the new-conversation screen. Defaults to false.
`searchParameters`
type: AgentStudioSearchParameters| optional
Search parameters keyed by index name. There's no default.
Each value supports filters, attributesToRetrieve, restrictSearchableAttributes, and distinct. This Agent Studio shape doesn't accept facetFilters.
askAi: {
assistantId: 'YOUR_ASSISTANT_ID',
searchParameters: {
docs: {
filters: 'language:en',
attributesToRetrieve: ['title', 'content', 'url'],
distinct: true,
},
},
}`indices`
type: string[]| optional
Index names for the Agent Studio search tool on this request. There's no default.
Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in searchParameters.
askAi: {
agentId: 'YOUR_ASSISTANT_ID',
indices: ['api_reference', 'docs_markdown'],
searchParameters: {
api_reference: {
filters: 'version:latest',
},
},
}`tools`
type: ToolCalls| optional
Custom Agent Studio tool renderers and handlers. Defaults to {}.
ToolCalls maps Agent Studio tool names to ToolDefinition objects. render converts the tool input and output to displayed text. onToolCall handles a client-side tool and must call addToolOutput when it produces a result. translations.callingToolText changes the pending label.
`memory`
type: Memory| optional
Agent Studio memory display and user token. Memory is disabled by default.
memory: {
enabled: true,
userToken: 'SERVER_GENERATED_JWT_TOKEN',
}enabled controls whether memory tool calls appear. userToken is the JWT sent in the x-algolia-secure-user-token header.
`promptSuggestions`
type: PromptSuggestions| optional
Prompt suggestions displayed with keyword results. There's no default.
promptSuggestions: {
indexName: 'docsearch_prompt_suggestions',
hitsPerPage: 3,
}The index records must contain a prompt attribute. hitsPerPage defaults to 3.
`DocSearchInstance`
`isReady`
type: readonly boolean
Whether the instance is mounted.
`isOpen`
type: readonly boolean
Whether the modal is open.
`open`
type: () => void
Opens keyword search.
`close`
type: () => void
Closes the modal.
`openAskAi`
type: (initialMessage?: InitialAskAiMessage) => void
Opens Ask AI with an optional query. Use with the AI-capable entry.
`destroy`
type: () => void
Unmounts DocSearch and marks the instance not ready.
Compatibility and deprecations
- The bundles target ES2017 browsers.
indexNameand rootsearchParametersremain supported but are deprecated. Move toindices.- The default entry uses Agent Studio. The v4 Ask AI transport and
askAi.agentStudioswitch aren't available. - The keyword-only
/docsearchexport is the smaller choice when you don't configure Ask AI.
Packages Website Docs Packages Modal Api (`packages/website/docs/packages/modal/api.mdx`)
title: Modal API reference
`DocSearchButton`
type: React.ComponentType<DocSearchButtonProps>
Renders the search trigger. It runs your onClick handler, then opens the modal through the nearest DocSearch provider.
DocSearchButtonProps accepts standard React button props and the following prop. Configure theme and keyboardShortcuts on DocSearch, not on this component.
`translations`
type: { buttonText?: string; buttonAriaLabel?: string }| optional
Sets the visible and accessible button text. Both values default to English labels.
`DocSearchModal`
type: React.ComponentType<DocSearchModalProps>
Renders a keyword-search modal when its provider is active. It renders in document.body unless you set portalContainer.
Required props
`appId`
type: string| required
Algolia application ID.
`apiKey`
type: string| required
Public API key with search permission.
`indices`
type: Array<string | DocSearchIndex>| required
The list of indices and their optional configuration used for search.
Search props
`facets`
type: Array<{ key: string; label?: string }>| optional
Adds filter controls that use facet values from the configured indices. Defaults to [].
`placeholder`
type: string| optional
Sets the search input placeholder. Defaults to Search docs. A translation can override this value.
`maxResultsPerGroup`
type: number| optional
Limits the displayed hits in each result group.
`transformItems`
type: (items: DocSearchHit[]) => DocSearchHit[]| optional
Changes hits before rendering. Defaults to the identity function.
`transformSearchClient`
type: (client: DocSearchTransformClient) => DocSearchTransformClient| optional
Wraps or changes the search client. Defaults to the identity function.
`navigator`
type: AutocompleteOptions['navigator']| optional
Controls link navigation.
`insights`
type: AutocompleteOptions['insights']| optional
Configures Algolia Insights. Defaults to false.
`resultBadgeKey`
type: string| optional
Reads a hit property and displays it as a result badge. Include the property in attributesToRetrieve.
Rendering and behavior props
`initialQuery`
type: string| optional
Prefills the search input. This value takes precedence over the provider value and defaults to '' if neither value is set.
`portalContainer`
type: DocumentFragment | Element| optional
Receives the modal portal. Defaults to document.body.
`hitComponent`
type: (props) => JSX.Element| optional
Renders an individual result. Defaults to the built-in hit component.
`resultsFooterComponent`
type: (props) => JSX.Element | null| optional
Renders content below the results. Defaults to null.
`footerAction`
type: React.ReactNode| optional
Renders a custom element in the modal footer, before the "Powered by Algolia" logo. Passing null renders nothing.
`disableUserPersonalization`
type: boolean| optional
Disables storing and using recent and favorite searches. Defaults to false.
`recentSearchesLimit`
type: number| optional
Limits saved and displayed recent searches. Defaults to 7.
`recentSearchesWithFavoritesLimit`
type: number| optional
Limits recent searches when favorites exist. Defaults to 4.
`getMissingResultsUrl`
type: ({ query }: { query: string }) => string| optional
Builds the missing-results report URL.
`translations`
type: ModalTranslations| optional
Supplies partial strings for searchBox, footer, facets, errorScreen, startScreen, noResultsScreen, and resultsScreen. Defaults to {}.
DocSearchModal receives theme, keyboardShortcuts, and close behavior from the provider. It doesn't accept these props directly.
`DocSearchIndex`
`name`
type: string| required
Index to search.
`searchParameters`
type: SearchParamsObject| optional
Sets search parameters for this index.
`DocSearchAskAiModal`
type: React.ComponentType<DocSearchAskAiModalProps>
Renders the Agent Studio-enabled modal. It accepts every DocSearchModal prop, requires askAi, and adds Agent Studio translations.
`askAi`
type: string | DocSearchAskAi| required
Sets the Agent Studio agent ID or the complete Agent Studio configuration.
`interceptAskAiEvent`
type: (message: InitialAskAiMessage) => boolean | void| optional
Runs before the default Ask AI action. Return true to prevent the action.
`translations`
type: DocSearchAskAiModalTranslations| optional
Adds askAiScreen, newConversation, and Agent Studio search-box strings to the search translations. Defaults to {}.
The component receives its active state and close behavior from DocSearch. It doesn't accept isAskAiActive, isHybridModeSupported, onAskAiToggle, onClose, theme, or keyboardShortcuts. See Hybrid Mode for cross-view behavior.
`DocSearchAskAi`
The object form of askAi. It accepts the following fields.
`agentId`
type: string| required
Agent Studio agent ID.
`appId`
type: string| optional
Overrides the root appId for Agent Studio.
`apiKey`
type: string| optional
Overrides the root apiKey for Agent Studio.
`suggestedQuestions`
type: boolean| optional
Shows configured suggested questions on the new-conversation screen. Defaults to false.
`searchParameters`
type: Record<string, AgentStudioIndexSearchParameters>| optional
Sends search parameters keyed by index name. AgentStudioIndexSearchParameters supports filters, attributesToRetrieve, restrictSearchableAttributes, and distinct. It doesn't support facetFilters.
`indices`
type: string[]| optional
Index names available to Agent Studio search tools. Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in searchParameters.
`tools`
type: Record<string, ToolDefinition>| optional
Handles and renders custom Agent Studio tools. Defaults to {}.
`memory`
type: { enabled?: boolean; userToken?: string }| optional
Displays memory tool activity and sends a secure user token.
`promptSuggestions`
type: { indexName: string; hitsPerPage?: number }| optional
Configures prompt suggestions in keyword search. hitsPerPage defaults to 3.
Custom tools
Each ToolDefinition accepts the following fields:
`render`
type: (params: { message: { input: unknown; output: unknown } }) => string| required
Renders the tool input and output.
`onToolCall`
type: (params: ToolCallParameters) => Promise<void> | void| optional
Handles a client-side tool call. ToolCallParameters includes input, addToolOutput, toolCallId, toolName, and the optional dynamic flag.
`translations`
type: { callingToolText?: string }| optional
Overrides the text shown while the tool runs.
When onToolCall handles a client-side tool, call addToolOutput with the result. Define the tools object outside your component or memoize it to keep its identity stable.
Memory
Set memory.enabled to render Agent Studio memory tool calls. Set memory.userToken to send the JSON Web Token (JWT) as the x-algolia-secure-user-token request header.
Generate the JWT on your server. Don't put signing secrets in browser code.
Exports
| Import path | Value exports | Type exports |
|---|---|---|
@docsearch/modal |
DocSearchButton, DocSearchModal, DocSearchAskAiModal |
DocSearchButtonProps, DocSearchModalProps, DocSearchAskAiModalProps |
@docsearch/modal/button |
DocSearchButton |
DocSearchButtonProps |
@docsearch/modal/modal |
DocSearchModal |
DocSearchModalProps |
@docsearch/modal/askai |
DocSearchAskAiModal |
DocSearchAskAiModalProps |
Packages Website Docs Packages React Api Reference (`packages/website/docs/packages/react/api-reference.mdx`)
title: React API reference
Components
`DocSearch`
type: React.ForwardRefExoticComponent<DocSearchProps>
Renders keyword search. It accepts the common props and forwards a DocSearchRef.
import { DocSearch } from '@docsearch/react';`DocSearchAI`
type: React.ForwardRefExoticComponent<DocSearchAIProps>
Renders keyword search and Ask AI. It accepts the common props, requires askAi, and forwards a DocSearchRef.
import { DocSearchAI } from '@docsearch/react';Common props
`appId`
type: string| required
Algolia application ID.
`apiKey`
type: string| required
Public API key with search permission.
`indices`
type: Array<string | DocSearchIndex>| optional
Indices to search in display order.
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={[
{
name: 'docs_en',
searchParameters: {
facetFilters: ['version:v5'],
},
},
'docs_fr',
]}
/>`facets`
type: DocSearchFacet[]| optional
Facet controls populated from the configured indices. Defaults to [].
DocSearch supports up to five facets. It ignores empty and duplicate keys, merges sorted values from all configured indices, and hides facets with no values. Configure each attribute for faceting in the Algolia index.
Users can select multiple values per facet. DocSearch combines values of the same facet with OR and different facets with AND when it builds facetFilters for each index. A selection replaces the index's configured facetFilters entries for that facet key and keeps entries for other keys. DocSearch also replaces a configured OR group, such as ['docusaurus_tag:default', 'docusaurus_tag:docs-default-current'], when the user has a selection for every key in the group.
`theme`
type: 'light' | 'dark'| optional
Theme written to document.documentElement.dataset.theme. By default, DocSearch doesn't change the current theme.
`placeholder`
type: string| optional
Search input placeholder. The active experience supplies the default.
`maxResultsPerGroup`
type: number| optional
Maximum results to show in each result group.
`transformItems`
type: (items: DocSearchHit[]) => DocSearchHit[]| optional
Transforms hits before DocSearch groups and renders them. Defaults to the identity function.
`hitComponent`
type: ({ hit, children }: HitComponentProps) => JSX.Element| optional
Renders one result link. The default component renders the standard result content.
function Hit({ hit, children }: HitComponentProps): JSX.Element {
return (
<a href={hit.url} data-result-type={hit.type}>
{children}
</a>
);
}Preserve children to retain the default hit content. hit is an InternalDocSearchHit | StoredDocSearchHit.
`resultsFooterComponent`
type: ({ state }: ResultsFooterComponentProps) => JSX.Element | null| optional
Renders below result collections. It receives the current Autocomplete state. By default, DocSearch doesn't render a footer.
`footerAction`
type: React.ReactNode| optional
Renders a custom element in the modal footer, before the "Powered by Algolia" logo. Passing null renders nothing.
function FooterAction(): JSX.Element {
return (
<a href="https://algolia.com">
Our other project
</a>
);
}
function Search() {
return (
<DocSearch
// ...
footerAction={<FooterAction />}
/>
);
}`transformSearchClient`
type: (client: SearchClient) => SearchClient| optional
Wraps or replaces the Algolia search client. Defaults to the identity function.
`disableUserPersonalization`
type: boolean| optional
Disables recent searches, favorites, and stored AI conversations. Defaults to false.
`initialQuery`
type: string| optional
Query to place in the input when the modal opens. Defaults to an empty string.
`navigator`
type: AutocompleteOptions['navigator']| optional
Autocomplete navigation implementation. Defaults to the Autocomplete navigator.
`translations`
type: DocSearchTranslations| optional
Overrides button and modal text. Defaults to English strings.
DocSearchTranslations groups overrides under button and modal. Modal groups include searchBox, footer, facets, errorScreen, startScreen, noResultsScreen, and resultsScreen. DocSearchAI also supports askAiScreen and newConversation.
<DocSearch
translations={{
button: {
buttonText: 'Search API docs',
buttonAriaLabel: 'Search API docs',
},
modal: {
searchBox: {
placeholderText: 'Search API docs',
},
facets: {
clearAllLabel: 'Reset filters',
},
},
}}
/>`getMissingResultsUrl`
type: ({ query }: { query: string }) => string| optional
Builds the no-results report URL.
`insights`
type: AutocompleteOptions['insights']| optional
Configures Algolia Insights. Defaults to false.
`portalContainer`
type: DocumentFragment | Element| optional
Element that receives the modal portal. Defaults to document.body.
`recentSearchesLimit`
type: number| optional
Maximum recent searches when the user has no favorites. Defaults to 7.
`recentSearchesWithFavoritesLimit`
type: number| optional
Maximum recent searches when the user has favorites. Defaults to 4.
`keyboardShortcuts`
type: DocSearchModalShortcuts| optional
Enables Ctrl/Cmd+K and / to open the modal. Both shortcuts are enabled by default. Escape always closes the modal.
`resultBadgeKey`
type: string| optional
Property path for a value on each hit. Paths support dot and array-index notation, such as hierarchy.lvl1, tags[2], and tags.2.
Add custom properties to attributesToRetrieve:
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={[
{
name: 'docs',
searchParameters: {
attributesToRetrieve: ['hierarchy.lvl0', 'content', 'url', 'version'],
},
},
]}
resultBadgeKey="version"
/>Primitive values render as text and arrays of primitives render as a comma-separated list. Set translations.modal.resultsScreen.resultBadgeLabelText to replace the default screen-reader label, Category.
Ask AI props
`askAi`
type: string | DocSearchAskAi| required
Agent Studio assistant ID or configuration. This prop is required by DocSearchAI.
`agentId`
type: string| required
Agent Studio agent ID.
`appId`
type: string| optional
Application ID for Agent Studio. Defaults to the root appId.
`apiKey`
type: string| optional
API key for Agent Studio. Defaults to the root apiKey.
`suggestedQuestions`
type: boolean| optional
Shows published assistant questions on the new-conversation screen. Defaults to false.
`searchParameters`
type: AgentStudioSearchParameters| optional
Search parameters keyed by index name. Each value supports filters, attributesToRetrieve, restrictSearchableAttributes, and distinct.
<DocSearchAI
askAi={{
agentId: 'YOUR_AGENT_ID',
searchParameters: {
docs: {
filters: 'language:en',
attributesToRetrieve: ['title', 'content', 'url'],
distinct: true,
},
},
}}
/>`indices`
type: string[]| optional
Index names for the Agent Studio search tool on this request. Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in searchParameters.
`tools`
type: ToolCalls| optional
Custom Agent Studio tool renderers and handlers. Defaults to {}. Each ToolDefinition requires render({ message }); onToolCall can handle client-side work and call addToolOutput({ output }).
`memory`
type: Memory| optional
Agent Studio memory display and user token. Memory is disabled by default. Memory.userToken is the user JWT sent to Agent Studio.
`promptSuggestions`
type: PromptSuggestions| optional
Prompt suggestions displayed with keyword results. indexName selects an index whose records contain a prompt attribute. hitsPerPage defaults to 3.
`interceptAskAiEvent`
type: (initialMessage: InitialAskAiMessage) => boolean | void| optional
Runs before DocSearch starts an Ask AI request. Return true to prevent the modal from toggling or sending the message. Use it to route Ask AI to another view.
`DocSearchRef`
Ref interface for DocSearch and DocSearchAI.
`isReady`
type: readonly boolean
Whether the provider is mounted.
`isOpen`
type: readonly boolean
Whether the modal is open.
`isSidepanelOpen`
type: readonly boolean
Whether the registered Sidepanel is open.
`isSidepanelSupported`
type: readonly boolean
Whether a Sidepanel is registered and the viewport isn't mobile.
`open`
type: () => void
Opens keyword search.
`close`
type: () => void
Closes the modal.
`openAskAi`
type: (initialMessage?: InitialAskAiMessage) => void
Opens Ask AI in the Sidepanel when hybrid mode is available, or in the modal otherwise.
`openSidepanel`
type: (initialMessage?: InitialAskAiMessage) => void
Opens a registered Sidepanel. Does nothing when no Sidepanel is registered.
InitialAskAiMessage requires query and can include messageId or suggestedQuestionId.
Compatibility and deprecations
react,react-dom, and@types/reactsupport versions>=16.8.0 <20.0.0.search-insightssupports versions>=1 <3and is optional.- The browser build targets ES2017.
UseDocSearchKeyboardEventsProps.onInputandsearchButtonRefremain accepted for compatibility but are deprecated.DocSearchis keyword-only in v5. UseDocSearchAIfor Ask AI.
Package exports
The root package exports DocSearch, DocSearchAI, DocSearchAskAiModal, DocSearchButton, DocSearchModal, useDocSearchKeyboardEvents, version, and public types.
| Import | Export |
|---|---|
@docsearch/react/askaiModal |
DocSearchAskAiModal |
@docsearch/react/button |
DocSearchButton |
@docsearch/react/docsearch |
DocSearch - Search only |
@docsearch/react/docsearchAi |
DocSearchAI and AI types |
@docsearch/react/modal |
DocSearchModal |
@docsearch/react/sidepanel |
DocSearchSidepanel and Sidepanel components |
@docsearch/react/sidepanelButton |
SidepanelButton, SidepanelButtonProps, SidepanelButtonTranslations, and ButtonVariant |
@docsearch/react/sidepanelPanel |
Sidepanel, SidepanelProps, SidepanelRef, and SidepanelTranslations - panel only, without the button |
@docsearch/react/useDocSearchKeyboardEvents |
useDocSearchKeyboardEvents |
@docsearch/react/useTheme |
useTheme |
@docsearch/react/version |
version |
For provider and modal composition, see Composable API. For modal and Sidepanel composition, see hybrid mode.
Style exports
Import @docsearch/css for the complete modal stylesheet. The React package also exports @docsearch/react/style and split style/variables, style/button, style/modal, style/askai, and style/sidepanel entries for component-level builds. See Styling.
Packages Website Docs Packages React Examples (`packages/website/docs/packages/react/examples.mdx`)
title: React examples
These examples build on the React getting started guide. Replace all placeholder credentials before using them.
Search multiple indices
Pass strings or per-index objects. Results follow the array order.
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={[
{
name: 'product_docs',
searchParameters: {
facetFilters: ['language:en'],
},
},
'api_reference',
]}
/>Add facet filters
Configure the attributes for faceting in Algolia, then expose up to five controls:
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs']}
facets={[
{ key: 'language', label: 'Language' },
{ key: 'version', label: 'Version' },
]}
/>DocSearch loads available values from all configured indices. When a user selects values, DocSearch replaces each index's configured facetFilters entries for that facet key with the selection and keeps entries for other keys. Users can select multiple values per facet. DocSearch combines them with OR, for example [['language:en', 'language:fr'], 'version:v2'].
Show a result badge
Retrieve the property and pass its path to resultBadgeKey:
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={[
{
name: 'product_docs',
searchParameters: {
attributesToRetrieve: [
'hierarchy.lvl0',
'hierarchy.lvl1',
'hierarchy.lvl2',
'hierarchy.lvl3',
'hierarchy.lvl4',
'hierarchy.lvl5',
'hierarchy.lvl6',
'content',
'type',
'url',
'version',
],
},
},
]}
resultBadgeKey="version"
translations={{
modal: {
resultsScreen: {
resultBadgeLabelText: 'Version',
},
},
}}
/>Nested paths such as hierarchy.lvl1 and tags[2] also work.
Customize result links
Use hitComponent to change the link while preserving DocSearch's result content:
function SearchHit({ hit, children }) {
return (
<a
href={hit.url}
data-index={hit.__autocomplete_indexName}
onClick={() => console.info('Opened result', hit.objectID)}
>
{children}
</a>
);
}
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs']}
hitComponent={SearchHit}
/>;Add a results footer
Use the Autocomplete state to show query-level information:
function ResultsFooter({ state }) {
const count = state.context.nbHits ?? 0;
return <p>{count} matching records</p>;
}
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs']}
resultsFooterComponent={ResultsFooter}
/>;Transform results
Return the hits in the order you want DocSearch to group and render them:
<DocSearch
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs']}
transformItems={(items) =>
items.filter((item) => item.hierarchy.lvl0 !== 'Archived')
}
/>Open search from another control
import { useRef } from 'react';
import { DocSearch, type DocSearchRef } from '@docsearch/react';
function Search() {
const searchRef = useRef<DocSearchRef>(null);
return (
<>
<button type="button" onClick={() => searchRef.current?.open()}>
Search documentation
</button>
<DocSearch
ref={searchRef}
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs']}
/>
</>
);
}Add Agent Studio search parameters
Use DocSearchAI. Key Ask AI search parameters by index name:
<DocSearchAI
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs']}
askAi={{
assistantId: 'YOUR_ASSISTANT_ID',
searchParameters: {
product_docs: {
filters: 'language:en AND version:v5',
attributesToRetrieve: ['title', 'content', 'url'],
restrictSearchableAttributes: ['title', 'content'],
distinct: true,
},
},
}}
/>See Get started with Agent Studio before configuring the component.
Add dynamic Agent Studio indices
Pass the index names Agent Studio should search for this request:
const askAi = {
agentId: 'YOUR_ASSISTANT_ID',
indices: ['product_docs', 'api_reference'],
searchParameters: {
product_docs: {
filters: 'language:en',
},
},
};
<DocSearchAI
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs', 'api_reference']}
askAi={askAi}
/>;Define stable objects outside the component, or memoize them, when they contain tools.
Add prompt suggestions
Show matching prompts next to keyword results:
<DocSearchAI
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs']}
askAi={{
assistantId: 'YOUR_ASSISTANT_ID',
suggestedQuestions: true,
promptSuggestions: {
indexName: 'docsearch_prompt_suggestions',
hitsPerPage: 3,
},
}}
/>suggestedQuestions shows published assistant questions on a new conversation. promptSuggestions searches your prompt index while the user types a keyword query.
Route Ask AI to another view
Return true from interceptAskAiEvent after handling the message:
<DocSearchAI
appId="YOUR_APP_ID"
apiKey="YOUR_SEARCH_API_KEY"
indices={['product_docs']}
askAi="YOUR_ASSISTANT_ID"
interceptAskAiEvent={(initialMessage) => {
openCustomAssistant(initialMessage);
return true;
}}
/>For the supported modal and Sidepanel integration, use hybrid mode.
Lazy-load the Sidepanel
Import the trigger from @docsearch/react/sidepanelButton, then dynamically import Sidepanel from @docsearch/react/sidepanelPanel. The button entry excludes the panel and its Ask AI dependencies. Dynamically importing the panel entry defers those dependencies until needed.
Don't statically import the button from @docsearch/react/sidepanel when you need this boundary. Tree shaking depends on the bundler: a production Bun build with both a static button import and a dynamic panel import from the shared @docsearch/react/sidepanel entry includes the AI SDK and Markdown renderer in the initial chunks. Using the dedicated sidepanelButton/sidepanelPanel entries keeps those dependencies deferred and avoids bundling the button twice.
/* Detailed source-code truncated for AI context efficiency. */Hover, focus, and touch start preload the module without opening the panel. Activation also loads it if preloading hasn't finished. This example disables the global shortcut because the panel's keyboard listener isn't mounted before activation, and unmounts the panel on close. To preserve an in-progress conversation, keep it mounted after the first activation and control visibility with isOpen.
For provider-based composition, @docsearch/sidepanel/button also uses the lightweight trigger entry. Keep the panel mounted when you need provider refs, keyboard shortcuts, or hybrid handoff before a user activates the trigger.
Packages Website Docs Packages Sidepanel Js Api (`packages/website/docs/packages/sidepanel-js/api.mdx`)
title: Sidepanel JS API reference toc_max_heading_level: 2
`sidepanel`
function sidepanel(props: SidepanelProps): SidepanelInstance;The function resolves container, mounts the component, and returns immediately. Use onReady or instance.isReady to detect the mounted state.
Mounting props
`container`
type: HTMLElement | string| required
Element or CSS selector that receives the Sidepanel application.
`environment`
type: typeof window| optional
Environment used to resolve a selector. Defaults to the browser window. A selector without a browser environment throws.
The function throws if a selector doesn't match an element.
Connection props
`appId`
type: string| required
Algolia application ID.
`apiKey`
type: string| required
Public API key with search permission.
`agentId`
type: string| required
Agent Studio agent ID.
UI props
`theme`
type: 'light' | 'dark'| optional
Sets data-theme on the document root while mounted.
`keyboardShortcuts`
type: { 'Ctrl/Cmd+I'?: boolean }| optional
Enables or disables the Sidepanel shortcut. The shortcut is enabled by default.
`button`
type: SidepanelButtonProps| optional
Configures the built-in button. Defaults to {}.
button accepts variant: 'floating' | 'inline' and translations.buttonText or translations.buttonAriaLabel.
`panel`
type: SidepanelPanelProps| optional
Configures layout, suggested questions, and translations. Defaults to {}.
panel accepts variant, side, pushSelector, width, expandedWidth, portalContainer, suggestedQuestions, translations, tools, memory, and indices. Panel-level tools, memory, and indices override their root values. Don't set panel.keyboardShortcuts; configure shortcuts at the root.
Callbacks
`onReady`
type: () => void| optional
Runs once after the component mounts.
`onOpen`
type: () => void| optional
Runs when the Sidepanel opens.
`onClose`
type: () => void| optional
Runs when the Sidepanel closes.
Use these Sidepanel-specific callbacks rather than the inherited React provider callback names.
Agent Studio options
`tools`
type: Record<string, ToolDefinition>| optional
Handles and renders custom Agent Studio tools. Defaults to {}.
`memory`
type: { enabled?: boolean; userToken?: string }| optional
Configures memory-tool rendering and authentication.
`indices`
type: string[]| optional
Index names available to Agent Studio. Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in searchParameters.
These fields are root props:
const assistant = sidepanel({
container: '#docsearch-sidepanel',
appId: 'YOUR_APPLICATION_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
agentId: 'YOUR_AGENT_ID',
memory: {
enabled: true,
userToken: userMemoryToken,
},
indices: ['docs', 'support_articles'],
searchParameters: {
docs: { filters: 'version:v5' },
support_articles: { filters: 'visibility:public' },
},
tools: {
getReleaseChannel: {
async onToolCall({ input, addToolOutput }) {
const channel = await readReleaseChannel(input);
await addToolOutput({ output: { channel } });
},
render({ message }) {
return `Release channel: ${message.output.channel}`;
},
},
},
});ToolDefinition requires render({ message: { input, output } }), which returns a string. It can also define onToolCall and translations.callingToolText. If you handle a client-side tool, call addToolOutput.
Generate memory.userToken on your server. The package sends it as x-algolia-secure-user-token.
`SidepanelInstance`
Calls to open and close before the internal ref is ready are no-ops.
InitialAskAiMessage is:
type InitialAskAiMessage = {
query: string;
messageId?: string;
suggestedQuestionId?: string;
};`isReady`
type: readonly boolean
Whether the component is mounted.
`isOpen`
type: readonly boolean
Whether the panel is open.
`open`
type: (initialMessage?: InitialAskAiMessage) => void
Opens the panel, optionally with a question or stored-message IDs.
`close`
type: () => void
Closes the panel.
`destroy`
type: () => void
Unmounts the component and marks the instance not ready.
Exports
@docsearch/sidepanel-js has one value export: the default sidepanel function.
It also exports the SidepanelProps, SidepanelInstance, and SidepanelCallbacks TypeScript types. It doesn't provide a named sidepanel export or package subpaths.
import sidepanel, {
type SidepanelCallbacks,
type SidepanelInstance,
type SidepanelProps,
} from '@docsearch/sidepanel-js';Packages Website Docs Packages Sidepanel Advanced Use Cases (`packages/website/docs/packages/sidepanel/advanced-use-cases.mdx`)
title: React Sidepanel advanced use cases
Push page content
Use the inline panel variant to add a margin to the first element that matches pushSelector. On screens up to 768 pixels wide, the panel overlays the page instead.
<SidepanelButton variant="inline" />
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
variant="inline"
side="left"
pushSelector="#documentation"
width="24rem"
expandedWidth="36rem"
/>Keep pushSelector narrow enough to identify one layout container. The implementation uses the first matching element and restores its inline margin and transition when it unmounts.
Render into another container
Both the floating button and panel default to document.body. Set portalContainer on the panel and portalcontainer on the button to use another element.
const assistantRoot = document.getElementById('assistant-root');
<DocSearch>
<SidepanelButton portalcontainer={assistantRoot} />
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
portalContainer={assistantRoot}
/>
</DocSearch>;An inline SidepanelButton renders where it appears in the React tree and doesn't use its portal container.
Control the panel with a ref
Attach a DocSearchRef to the provider. openSidepanel accepts an optional initial message.
import { DocSearch, type DocSearchRef } from '@docsearch/core';
import { Sidepanel } from '@docsearch/sidepanel';
import { useRef } from 'react';
export function Support() {
const docsearchRef = useRef<DocSearchRef>(null);
return (
<DocSearch ref={docsearchRef}>
<button
type="button"
onClick={() =>
docsearchRef.current?.openSidepanel({
query: 'How do I rotate an API key?',
})
}
>
Ask about API keys
</button>
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
/>
</DocSearch>
);
}Call the method after the Sidepanel has mounted and registered its view. Check isSidepanelOpen to read its open state. See Hybrid Mode for cross-view ref behavior.
Keep a controlled panel mounted
The low-level Sidepanel from @docsearch/react/sidepanel accepts isOpen, onOpen, and onClose. Unlike Sidepanel from @docsearch/sidepanel, it doesn't require a DocSearch provider. Render it on the client and keep it mounted when closed to preserve the current conversation, draft prompt, and panel state. Unmounting discards that in-memory state; saved conversation history is separate.
The component owns closed-state visibility and interaction: its stylesheet hides the panel, and the closed root is inert, excluding its descendants from keyboard navigation and the accessibility tree. Reopening restores interaction without resetting the conversation. Closing doesn't stop an active response.
The panel focuses its prompt when opened on desktop and blurs the prompt when closed. It doesn't autofocus on mobile or restore focus to your trigger. Your integration owns isOpen and focus restoration. Route close actions through a handler that returns focus to the trigger, or another appropriate element if the trigger no longer exists.
import { Sidepanel } from '@docsearch/react/sidepanel';
import { useCallback, useRef, useState, type JSX } from 'react';
import '@docsearch/react/style';
import '@docsearch/react/style/sidepanel';
export function ControlledAssistant(): JSX.Element {
const [isOpen, setIsOpen] = useState(false);
const triggerRef = useRef<HTMLButtonElement>(null);
const open = useCallback(() => setIsOpen(true), []);
const close = useCallback(() => {
triggerRef.current?.focus();
setIsOpen(false);
}, []);
return (
<>
<button type="button" ref={triggerRef} aria-expanded={isOpen} onClick={open}>
Ask AI
</button>
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
isOpen={isOpen}
onOpen={open}
onClose={close}
/>
</>
);
}Handle Agent Studio tools
Key each client tool by the name emitted by your agent. Always return tool output through addToolOutput when you provide onToolCall.
const tools = {
getReleaseChannel: {
translations: { callingToolText: 'Reading release settings' },
async onToolCall({ input, addToolOutput }) {
const channel = await readReleaseChannel(input);
await addToolOutput({ output: { channel } });
},
render({ message }) {
const output = message.output as { channel: string };
return `Release channel: ${output.channel}`;
},
},
};
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
tools={tools}
/>;Define tools outside the component or memoize it. Tool errors don't render a tool result.
Enable memory
Pass a server-generated Agent Studio user JWT. enabled controls whether memory tool activity appears in the conversation; userToken authenticates the user's memory requests.
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
memory={{
enabled: true,
userToken: userMemoryToken,
}}
/>Don't generate or sign the token in the browser.
Provide dynamic indices
Use indices to select the indices Agent Studio can search at request time.
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
agentId="YOUR_AGENT_ID"
searchParameters={{
docs: { filters: 'version:v5' },
support_articles: { filters: 'visibility:public' },
}}
indices={['docs', 'support_articles']}
/>Search parameters are keyed by index name. See the Sidepanel API for the supported fields.
Packages Website Docs Packages Sidepanel Api (`packages/website/docs/packages/sidepanel/api.mdx`)
title: React Sidepanel API reference toc_max_heading_level: 2
`Sidepanel`
Render Sidepanel inside DocSearch from @docsearch/core.
Set theme on DocSearch; SidepanelProps omits it. Set lifecycle callbacks such as onSidepanelOpen and onSidepanelClose on the provider. Don't pass inherited onOpen or onClose callbacks to Sidepanel, because they replace the wrapper's state handlers.
Connection props
`appId`
type: string| required
Algolia application ID.
`apiKey`
type: string| required
Public API key with search permission.
`agentId`
type: string| required
Agent Studio agent ID.
`searchParameters`
type: Record<string, AgentStudioIndexSearchParameters>| optional
Search parameters keyed by index name.
AgentStudioIndexSearchParameters supports filters, attributesToRetrieve, restrictSearchableAttributes, and distinct.
Layout props
`variant`
type: 'floating' | 'inline'| optional
Overlays the page or pushes matching page content on desktop. Defaults to 'floating'.
`side`
type: 'left' | 'right'| optional
Sets the side from which the panel opens. Defaults to 'right'.
`pushSelector`
type: string| optional
Selects the first element pushed by the inline panel. Defaults to '#root, main, .app, body'.
`width`
type: number | string| optional
Sets the normal width. Numbers use pixels. Defaults to 360.
`expandedWidth`
type: number | string| optional
Sets the expanded width. Numbers use pixels. Defaults to 580.
`portalContainer`
type: DocumentFragment | Element | null| optional
Receives the panel portal. Defaults to document.body.
Behavior props
`keyboardShortcuts`
type: { 'Ctrl/Cmd+I'?: boolean }| optional
Enables or disables the Sidepanel shortcut. The shortcut is enabled by default.
`suggestedQuestions`
type: boolean| optional
Whether to show Agent Studio suggested questions on the new-conversation screen. Defaults to false.
`translations`
type: SidepanelTranslations| optional
Supplies partial strings for header, promptForm, conversationScreen, newConversationScreen, and logo. Defaults to {}.
`tools`
type: Record<string, ToolDefinition>| optional
Handles and renders custom Agent Studio tools. Defaults to {}.
`memory`
type: { enabled?: boolean; userToken?: string }| optional
Configures Agent Studio memory rendering and authentication.
`indices`
type: string[]| optional
Index names available to Agent Studio. Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in searchParameters.
Translation groups
| Group | Keys |
|---|---|
header |
title, conversationHistoryTitle, newConversationText, viewConversationHistoryText |
promptForm |
promptPlaceholderText, promptAnsweringText, promptAskAnotherQuestionText, promptDisclaimerText, promptLabelText, promptAriaLabelText |
newConversationScreen |
titleText, introductionText |
logo |
poweredByText |
conversationScreen |
Tool status, source, copy, feedback, error, disclaimer, and suggested-prompt strings exposed by ConversationScreenTranslations |
Agent Studio options
V5 uses Agent Studio for Sidepanel conversations. It doesn't expose an agentStudio prop.
`ToolDefinition`
type ToolDefinition = {
render: (params: { message: { input: unknown; output: unknown } }) => string;
onToolCall?: (params: {
input: unknown;
addToolOutput: (props: { output: unknown }) => Promise<void>;
toolCallId: string;
toolName: string;
dynamic?: boolean;
}) => Promise<void> | void;
translations?: { callingToolText?: string };
};`memory`
enabled defaults to false and controls memory-tool status rendering. userToken is sent as the x-algolia-secure-user-token header.
`SidepanelButton`
`variant`
type: 'floating' | 'inline'| optional
Renders an icon-only floating button or an inline button with text. Defaults to 'floating'.
`translations`
type: { buttonText?: string; buttonAriaLabel?: string }| optional
Changes visible and accessible text. buttonText applies to the inline variant. Defaults to the English labels.
`portalcontainer`
type: DocumentFragment | Element | null| optional
Receives the floating button portal. Defaults to document.body.
The wrapper supplies its click handler and keyboard shortcut configuration from DocSearch. An inline button renders at its position in the React tree.
Programmatic control
Sidepanel doesn't expose its lower-level SidepanelRef directly. Attach a DocSearchRef to the provider and use:
`openSidepanel`
type: (initialMessage?: InitialAskAiMessage) => void
Opens a registered Sidepanel.
`close`
type: () => void
Returns the provider to its ready state.
`isSidepanelOpen`
type: boolean
Whether the Sidepanel is open.
`isReady`
type: boolean
Whether the provider is mounted.
InitialAskAiMessage is { query: string; messageId?: string; suggestedQuestionId?: string }. See the @docsearch/core API for the full ref.
Exports
| Import path | Value exports | Type exports |
|---|---|---|
@docsearch/sidepanel |
Sidepanel, SidepanelButton |
SidepanelProps, SidepanelButtonProps |
@docsearch/sidepanel/sidepanel |
Sidepanel |
SidepanelProps |
@docsearch/sidepanel/button |
SidepanelButton |
SidepanelButtonProps |
Import @docsearch/sidepanel/button and dynamically import @docsearch/sidepanel/sidepanel to defer the panel and its Ask AI dependencies, the same way as the React lazy-load example. Internally, these entries build on the equivalent @docsearch/react/sidepanelButton and @docsearch/react/sidepanelPanel entries, so no further split is needed.
--- METRICS ---
- Files Extracted: 54
- Estimated Token Budget: ~70551 tokens
- Canonical Reference: https://codewiki.google/github.com/algolia/docsearch