---
title: API Reference
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import useBaseUrl from '@docusaurus/useBaseUrl';

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', },
    { label: 'React', value: 'react', }
  ]
}>
<TabItem value="js">

## `container`

> `type: string | HTMLElement` | **required**

The container for the DocSearch search box. You can either pass a [CSS selector][5] or an [Element][6]. If there are several containers matching the selector, DocSearch picks up the first one.

## `environment`

> `type: typeof window` | `default: window` | **optional**

The environment in which your application is running.

This is useful if you’re using DocSearch in a different context than window.

</TabItem>
</Tabs>

## `appId`

> `type: string` | **required**

Your Algolia application ID.

## `apiKey`

> `type: string` | **required**

Your Algolia Search API key.

## `indices`

> `type: Array<string | DocSearchIndex>`

The list of indices and their _optional_ `searchParameters` to be used for keyword search.

[Algolia Search Parameters][7]

:::tip

The ordering matters in the list, as results are ordered based on `indices` order.

:::

> While `indexName` is in deprecation, it is required to pass either `indices` or `indexName`. Not passing either will result in an `Error` being thrown.

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', },
    { label: 'React', value: 'react', }
  ]
}>
<TabItem value="js">

```js
docsearch({
  // ...
  indices: ['YOUR_ALGOLIA_INDEX'],
  // ...
});
```

in case you want to use custom `searchParameters` for the index

```js
docsearch({
  // ...
  indices: [
    {
      name: 'YOUR_ALGOLIA_INDEX',
      searchParameters: {
        facetFilters: ['language:en'],
        // ...
      },
    },
  ],
  // ...
});
```

</TabItem>

<TabItem value="react">

```jsx
<DocSearch
  // ...
  indices={['YOUR_ALGOLIA_INDEX']}
  // ...
/>
```

in case you want to use custom `searchParameters` for the index

```jsx
<DocSearch
  // ...
  indices={[
    {
      name: 'YOUR_ALGOLIA_INDEX',
      searchParameters: {
        facetFilters: ['language:en'],
        // ...
      },
    },
  ]}
  // ...
/>
```

</TabItem>
</Tabs>

## `indexName`

> `type: string` | **deprecated**

:::warning[Deprecation warning]

`indexName` is currently being planned for deprecation. The new recommended property to use is `indices`.

:::

Your Algolia index name.

> While `indexName` is in deprecation, it is required to pass either `indices` or `indexName`. Not passing either will result in an `Error` being thrown.

## `placeholder`

> `type: string` | `default: "Search docs"` | **optional**

The placeholder of the input of the DocSearch pop-up modal. Note: If you add a placeholder it will replace the dynamic placeholder based on askAi, It would be better to edit [translations](#translations)

## `askAi`

> `type: AskAiObject` | `string` | **optional**

Your Algolia Assistant ID.

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', },
    { label: 'React', value: 'react', }
  ]
}>
<TabItem value="js">

```js
docsearch({
  // ...
  askAi: 'YOUR_ALGOLIA_ASSISTANT_ID',
  // ...
});
```

or if you want to use different credentials for askAi and add search parameters

```js
docsearch({
  // ...
  askAi: {
    indexName: 'ANOTHER_INDEX_NAME',
    apiKey: 'ANOTHER_SEARCH_API_KEY',
    appId: 'ANOTHER_APP_ID',
    assistantId: 'YOUR_ALGOLIA_ASSISTANT_ID',
    searchParameters: {
      // Filtering parameters
      facetFilters: ['language:en', 'version:latest'],
      filters: 'type:content AND language:en',

      // Content control parameters
      attributesToRetrieve: ['title', 'content', 'url'],
      restrictSearchableAttributes: ['title', 'content'],

      // Deduplication
      distinct: true,
    },

    // Enables/disables showing suggested questions on Ask AI's new conversation screen
    // NOTE: Only available with version >= 4.3
    suggestedQuestions: true,
  },
  // ...
});
```

</TabItem>

<TabItem value="react">

```jsx
<DocSearch
  // ...
  askAi="YOUR_ALGOLIA_ASSISTANT_ID"
/>
```

in case you want to use different credentials for askAi

```jsx
<DocSearch
  // ...
  askAi={{
    indexName: 'ANOTHER_INDEX_NAME',
    apiKey: 'ANOTHER_SEARCH_API_KEY',
    appId: 'ANOTHER_APP_ID',
    assistantId: 'YOUR_ALGOLIA_ASSISTANT_ID',
    searchParameters: {
      // Filtering parameters
      facetFilters: ['language:en', 'version:latest'],
      filters: 'type:content AND language:en',

      // Content control parameters
      attributesToRetrieve: ['title', 'content', 'url'],
      restrictSearchableAttributes: ['title', 'content'],

      // Deduplication
      distinct: true,
    },

    // Enables/disables showing suggested questions on Ask AI's new conversation screen
    // NOTE: Only available with version >= 4.3
    suggestedQuestions: true,
  }}
/>
```

</TabItem>
</Tabs>

:::tip[Ask AI supports these essential search parameters for optimal performance:]

- **Filtering**: `facetFilters: ['type:content']` - Filter by language, version, or content type
- **Complex filtering**: `filters: 'type:content AND language:en'` - Apply complex filtering rules
- **Content control**: `attributesToRetrieve: ['title', 'content', 'url']` - Control which attributes are retrieved
- **Search scope**: `restrictSearchableAttributes: ['title', 'content']` - Limit search to specific fields
- **Deduplication**: `distinct: true` - Remove duplicate results

These parameters provide the essential functionality for Ask AI while keeping the API simple and focused.

:::

## `agentStudio`

> `type: boolean` | **optional** | **experimental**

:::warning[Experimental]

`agentStudio` is currently an experimental property. It is targeted to be stable in release `5.0.0`.

:::

If `agentStudio` is true, the Ask AI chat will use Algolia's [Agent Studio][12] as the chat backend instead of the Ask AI backend. Learn more on [Algolia Agent Studio Docs][13].

## `searchParameters`

> `type: SearchParameters` | **optional** | **deprecated**

:::warning[Deprecation warning]

`searchParameters` is currently being planned for deprecation. The new recommended property to use is `indices`.

:::

The [Algolia Search Parameters][7].

## `transformItems`

> `type: function` | `default: items => items` | **optional**

Receives the items from the search response, and is called before displaying them. Should return a new array with the same shape as the original array. Useful for mapping over the items to transform, and remove or reorder them.

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', },
    { label: 'React', value: 'react', }
  ]
}>
<TabItem value="js">

```js
docsearch({
  // ...
  transformItems(items) {
    return items.map((item) => ({
      ...item,
      content: item.content.toUpperCase(),
    }));
  },
});
```

</TabItem>

<TabItem value="react">

```jsx
<DocSearch
  // ...
  transformItems={(items) => {
    return items.map((item) => ({
      ...item,
      content: item.content.toUpperCase(),
    }));
  }}
/>
```

</TabItem>
</Tabs>

## `hitComponent`

> `type: ({ hit, children }, { html }) => JSX.Element | string | Function` | `default: Hit` | **optional**

The component to display each item. Supports template patterns:

- **HTML strings with html helper** (recommended for JS CDN): `({ hit, children }, { html }) => html...`
- **JSX templates** (for React/Preact): `({ hit, children }) => <div>...</div>`
- **Function-based templates**: `(props) => string | JSX.Element | Function`

You get access to the `hit` object which contains all the data for the search result, and `children` which is the default rendered content.

See the [default implementation][8].

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', },
    { label: 'React', value: 'react', }
  ]
}>
<TabItem value="js">

```js
docsearch({
  // ...
  hitComponent({ hit, children }, { html }) {
    // Using HTML strings with html helper
    return html`
      <a href="${hit.url}" class="custom-hit-class">
        <div class="hit-icon">🔍</div>
        <div class="hit-content">${children}</div>
      </a>
    `;
  },
});
```

</TabItem>

<TabItem value="react">

```jsx
<DocSearch
  // ...
  hitComponent={({ hit, children }) => {
    // Using JSX templates
    return (
      <a href={hit.url} className="custom-hit-class">
        <div className="hit-icon">🔍</div>
        <div className="hit-content">{children}</div>
      </a>
    );
  }}
/>
```

</TabItem>
</Tabs>

## `transformSearchClient`

> `type: function` | `default: DocSearchTransformClient => DocSearchTransformClient` | **optional**

Useful for transforming the [Algolia Search Client][10], for example to [debounce search queries][9]

## `disableUserPersonalization`

> `type: boolean` | `default: false` | **optional**

Disable saving recent searches and favorites to the local storage.

## `initialQuery`

> `type: string` | **optional**

The search input initial query.

## `navigator`

> `type: Navigator` | **optional**

An implementation of [Algolia Autocomplete][1]’s Navigator API to redirect the user when opening a link.

Learn more on the [Navigator API][11] documentation.

## `translations`

> `type: Partial<DocSearchTranslations>` | `default: docSearchTranslations` | **optional**

Allow translations of any raw text and aria-labels present in the DocSearch button or modal components.

<details>
<summary>docSearchTranslations</summary>
<div>

```ts
const translations: DocSearchTranslations = {
  button: {
    buttonText: 'Search',
    buttonAriaLabel: 'Search',
  },
  modal: {
    searchBox: {
      clearButtonTitle: 'Clear',
      clearButtonAriaLabel: 'Clear the query',
      closeButtonText: 'Close',
      closeButtonAriaLabel: 'Close',
      placeholderText: undefined, // fallback: 'Search docs' or 'Search docs or ask AI a question'
      placeholderTextAskAi: undefined, // fallback: 'Ask another question...'
      placeholderTextAskAiStreaming: 'Answering...',
      // can only be one of the following
      // https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/enterkeyhint#value
      enterKeyHint: 'search',
      enterKeyHintAskAi: 'enter',
      searchInputLabel: 'Search',
      backToKeywordSearchButtonText: 'Back to keyword search',
      backToKeywordSearchButtonAriaLabel: 'Back to keyword search',
      newConversationPlaceholder: 'Ask a question',
      conversationHistoryTitle: 'My conversation history',
      startNewConversationText: 'Start a new conversation',
      viewConversationHistoryText: 'Conversation history'
    },
    startScreen: {
      recentSearchesTitle: 'Recent',
      noRecentSearchesText: 'No recent searches',
      saveRecentSearchButtonTitle: 'Save this search',
      removeRecentSearchButtonTitle: 'Remove this search from history',
      favoriteSearchesTitle: 'Favorite',
      removeFavoriteSearchButtonTitle: 'Remove this search from favorites',
      recentConversationsTitle: 'Recent conversations',
      removeRecentConversationButtonTitle:
        'Remove this conversation from history',
    },
    errorScreen: {
      titleText: 'Unable to fetch results',
      helpText: 'You might want to check your network connection.',
    },
    noResultsScreen: {
      noResultsText: 'No results found for',
      suggestedQueryText: 'Try searching for',
      reportMissingResultsText: 'Believe this query should return results?',
      reportMissingResultsLinkText: 'Let us know.',
    },
    resultsScreen: {
      askAiPlaceholder: 'Ask AI: ',
      noResultsAskAiPlaceholder: 'Didn't find it in the docs? Ask AI to help: ',
    },
    askAiScreen: {
      disclaimerText:
        'Answers are generated with AI which can make mistakes. Verify responses.',
      relatedSourcesText: 'Related sources',
      thinkingText: 'Thinking...',
      copyButtonText: 'Copy',
      copyButtonCopiedText: 'Copied!',
      copyButtonTitle: 'Copy',
      likeButtonTitle: 'Like',
      dislikeButtonTitle: 'Dislike',
      thanksForFeedbackText: 'Thanks for your feedback!',
      preToolCallText: 'Searching...',
      duringToolCallText: 'Searching for ',
      afterToolCallText: 'Searched for',
      // If provided, these override the default rendering of aggregated tool calls:
      aggregatedToolCallNode: undefined, // (queries: string[], onSearchQueryClick: (query: string) => void) => React.ReactNode
      aggregatedToolCallText: undefined, // (queries: string[]) => { before?: string; separator?: string; lastSeparator?: string; after?: string }
      // Text to show when user has stopped streaming a message
      stoppedStreamingText: 'You stopped this response',
    },
    footer: {
      selectText: 'Select',
      submitQuestionText: 'Submit question',
      selectKeyAriaLabel: 'Enter key',
      navigateText: 'Navigate',
      navigateUpKeyAriaLabel: 'Arrow up',
      navigateDownKeyAriaLabel: 'Arrow down',
      closeText: 'Close',
      backToSearchText: 'Back to search',
      closeKeyAriaLabel: 'Escape key',
      poweredByText: 'Powered by',
    },
    newConversation: {
      newConversationTitle: 'How can I help you today?',
      newConversationDescription: 'I search through your documentation to help you find setup guides, feature details and troubleshooting tips, fast.'
    }
  },
};
```

</div>
</details>

## `getMissingResultsUrl`

> `type: ({ query: string }) => string` | **optional**

Function to return the URL of your documentation repository.

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', },
    { label: 'React', value: 'react', }
  ]
}>
<TabItem value="js">

```js
docsearch({
  // ...
  getMissingResultsUrl({ query }) {
    return `https://github.com/algolia/docsearch/issues/new?title=${query}`;
  },
});
```

</TabItem>

<TabItem value="react">

```jsx
<DocSearch
  // ...
  getMissingResultsUrl={({ query }) => {
    return `https://github.com/algolia/docsearch/issues/new?title=${query}`;
  }}
/>
```

</TabItem>
</Tabs>

When provided, an informative message wrapped with your link will be displayed on no results searches. The default text can be changed using the [translations](#translations) property.

<div className="uil-ta-center">
  <img
    src={useBaseUrl('img/assets/noResultsScreen.png')}
    alt="No results screen with informative message"
  />
</div>

## `keyboardShortcuts`

> `type: KeyboardShortcuts` | **optional**

Configuration for keyboard shortcuts that trigger the search modal.

### Default behavior:

- `Ctrl/Cmd+K` - Opens and closes the search modal
- `/` - Opens the search modal (doesn't close)

### Interface:

```typescript
interface KeyboardShortcuts {
  'Ctrl/Cmd+K'?: boolean; // default: true
  '/'?: boolean; // default: true
}
```

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', },
    { label: 'React', value: 'react', }
  ]
}>
<TabItem value="js">

```js
// Default - all shortcuts enabled
docsearch({
  // ...
});

// Disable slash shortcut
docsearch({
  // ...
  keyboardShortcuts: { '/': false },
});

// Disable Ctrl/Cmd+K shortcut (also hides button hint)
docsearch({
  // ...
  keyboardShortcuts: { 'Ctrl/Cmd+K': false },
});

// Disable all keyboard shortcuts
docsearch({
  // ...
  keyboardShortcuts: { 'Ctrl/Cmd+K': false, '/': false },
});
```

</TabItem>

<TabItem value="react">

```jsx
{
  /* Default - all shortcuts enabled */
}
<DocSearch
// ...
/>;

{
  /* Disable slash shortcut */
}
<DocSearch
  // ...
  keyboardShortcuts={{ '/': false }}
/>;

{
  /* Disable Ctrl/Cmd+K shortcut (also hides button hint) */
}
<DocSearch
  // ...
  keyboardShortcuts={{ 'Ctrl/Cmd+K': false }}
/>;

{
  /* Disable all keyboard shortcuts */
}
<DocSearch
  // ...
  keyboardShortcuts={{ 'Ctrl/Cmd+K': false, '/': false }}
/>;
```

</TabItem>
</Tabs>

:::info[Keyboard Shortcut Behavior]

- **Ctrl/Cmd+K**: Toggle shortcut that both opens and closes the modal
- **/**: Character shortcut that only opens the modal (prevents interference with search typing)
- **Escape**: Always works to close the modal regardless of Configuration

:::

## `resultsFooterComponent`

> `type: ({ state }, { html }) => JSX.Element | string | Function` | **optional**

The component to display below the search results. Supports template patterns:

- **HTML strings with html helper** (recommended for JS CDN): `({ state }, { html }) => html...`
- **JSX templates** (for React/Preact): `({ state }) => <div>...</div>`
- **Function-based templates**: `(props) => string | JSX.Element | Function`

You get access to the [current state](https://github.com/algolia/autocomplete/blob/next/packages/autocomplete-core/src/types/AutocompleteState.ts) which allows you to retrieve the number of hits returned, the query etc.

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', },
    { label: 'React', value: 'react', }
  ]
}>
<TabItem value="js">

```js
docsearch({
  // ...
  resultsFooterComponent({ state }, { html }) {
    // Using HTML strings with html helper
    return html`
      <div class="DocSearch-HitsFooter">
        <a href="https://docsearch.algolia.com/apply" target="_blank">
          See all ${state.context.nbHits} results
        </a>
      </div>
    `;
  },
});
```

</TabItem>

<TabItem value="react">

```jsx
<DocSearch
  // ...
  resultsFooterComponent={({ state }) => {
    // Using JSX templates
    return (
      <div className="DocSearch-HitsFooter">
        <a href="https://docsearch.algolia.com/apply" target="_blank">
          See all {state.context.nbHits} results
        </a>
      </div>
    );
  }}
/>
```

</TabItem>
</Tabs>

## `maxResultsPerGroup`

> `type: number` | **optional**

The maximum number of results to display per search group. Default is 5.

[You can find a working example without JSX in this sandbox](https://codesandbox.io/s/docsearch-v3-maxresultspergroup-without-jsx-ct9m22?file=/src/index.js)

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js', }
  ]
}>
<TabItem value="js">

```js
docsearch({
  // ...
  maxResultsPerGroup: 7,
});
```

</TabItem>

</Tabs>

## `recentSearchesLimit`

> `type: number` | `default: 7` | **optional**

The maximum number of recent searches that are stored for the user. Default is 7.

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js' },
    { label: 'React', value: 'react' }
  ]}
>
<TabItem value="js">

```js
docsearch({
  // ...
  recentSearchesLimit: 12,
  // ...
});
```

</TabItem>

<TabItem value="react">

```jsx
<DocSearch
  // ...
  recentSearchesLimit={12}
  // ...
/>
```

</TabItem>
</Tabs>

## `recentSearchesWithFavoritesLimit`

> `type: number` | `default: 4` | **optional**

The maximum number of recent searches that are stored when the user has favorited searches. Default is 4.

<Tabs
  groupId="language"
  defaultValue="js"
  values={[
    { label: 'JavaScript', value: 'js' },
    { label: 'React', value: 'react' }
  ]}
>
<TabItem value="js">

```js
docsearch({
  // ...
  recentSearchesWithFavoritesLimit: 5,
  // ...
});
```

</TabItem>

<TabItem value="react">

```jsx
<DocSearch
  // ...
  recentSearchesWithFavoritesLimit={5}
  // ...
/>
```

</TabItem>
</Tabs>

## `portalContainer` (React-only)

> `type: Element | DocumentFragment` | `default: document.body` | **optional**

The element where the DocSearch modal will be portaled. Use this when you need the overlay to render in a custom DOM node—for example when working inside a shadow root, a specific layout container, or a modal manager. When omitted, the modal portals to `document.body`.

:::warning

This prop only exists in `@docsearch/react`. If you are using **`@docsearch/js`**, use the [`container`](#container) option instead—the value you pass there is both the **mount point** of the search button _and_ the portal target for the modal.

:::

<Tabs
  groupId="language"
  defaultValue="react"
  values={[{ label: 'React', value: 'react' }, { label: 'JavaScript', value: 'js' }]}
>
<TabItem value="react">

```jsx
// assume you have a dedicated modal root in your html
<div id="modal-root" />;

const portalEl = document.getElementById('modal-root');

<DocSearch
  appId="YOUR_APP_ID"
  apiKey="YOUR_SEARCH_API_KEY"
  indexName="YOUR_INDEX_NAME"
  // render the modal inside #modal-root instead of document.body
  portalContainer={portalEl}
/>;
```

</TabItem>

<TabItem value="js">

```js
docsearch({
  // the element that will **contain the button** and **host the modal portal**
  container: '#modal-root',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
});
```

</TabItem>
</Tabs>

[1]: https://www.algolia.com/doc/ui-libraries/autocomplete/introduction/what-is-autocomplete/
[2]: https://github.com/algolia/docsearch/
[3]: https://github.com/algolia/docsearch/tree/master
[4]: /docs/legacy/dropdown
[5]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors
[6]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
[7]: https://www.algolia.com/doc/api-reference/search-api-parameters/
[8]: https://github.com/algolia/docsearch/blob/main/packages/docsearch-react/src/Hit.tsx
[9]: https://codesandbox.io/s/docsearch-v3-debounced-search-gnx87
[10]: https://www.algolia.com/doc/api-client/getting-started/what-is-the-api-client/javascript/?client=javascript
[11]: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/keyboard-navigation/
[12]: https://www.algolia.com/products/ai/agent-studio
[13]: https://www.algolia.com/doc/guides/algolia-ai/agent-studio
