> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/algolia/docsearch/llms.txt
> Use this file to discover all available pages before exploring further.

# Vanilla JavaScript Integration

> Learn how to integrate DocSearch into any HTML/JavaScript website

DocSearch can be easily integrated into any website using vanilla JavaScript. This guide shows you how to add DocSearch to static sites, HTML pages, or any JavaScript application.

## Overview

The `@docsearch/js` package provides a simple JavaScript API that works in any browser environment. You can use it with or without a build tool.

## Installation

<Tabs>
  <Tab title="Package Manager">
    Install DocSearch using your preferred package manager:

    <CodeGroup>
      ```bash npm theme={null}
      npm install @docsearch/js @docsearch/css
      ```

      ```bash yarn theme={null}
      yarn add @docsearch/js @docsearch/css
      ```

      ```bash pnpm theme={null}
      pnpm add @docsearch/js @docsearch/css
      ```
    </CodeGroup>

    Then import in your JavaScript:

    ```js theme={null}
    import docsearch from '@docsearch/js';
    import '@docsearch/css';
    ```
  </Tab>

  <Tab title="CDN">
    Load DocSearch directly from a CDN (no build step required):

    ```html theme={null}
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>My Documentation</title>
      
      <!-- DocSearch CSS -->
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@4" />
    </head>
    <body>
      <div id="docsearch"></div>
      
      <!-- DocSearch JS -->
      <script src="https://cdn.jsdelivr.net/npm/@docsearch/js@4"></script>
    </body>
    </html>
    ```
  </Tab>
</Tabs>

## Quick Start

<Steps>
  <Step title="Add a container element">
    Add a container element where DocSearch will render the search button:

    ```html theme={null}
    <div id="docsearch"></div>
    ```

    <Note>
      Use a container element (like `<div>`), not an `<input>`. DocSearch generates a fully accessible search button for you.
    </Note>
  </Step>

  <Step title="Initialize DocSearch">
    Call the `docsearch()` function with your configuration:

    ```js theme={null}
    docsearch({
      container: '#docsearch',
      appId: 'YOUR_APP_ID',
      apiKey: 'YOUR_SEARCH_API_KEY',
      indexName: 'YOUR_INDEX_NAME',
    });
    ```
  </Step>

  <Step title="Test it">
    Open your page and press `Ctrl+K` (or `Cmd+K` on Mac) to open the search modal. You can also click the search button that DocSearch creates.
  </Step>
</Steps>

## Complete HTML Example

Here's a complete working example using the CDN:

```html title="index.html" theme={null}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Documentation</title>
  
  <!-- DocSearch CSS -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@4" />
  
  <style>
    body {
      font-family: system-ui, -apple-system, sans-serif;
      max-width: 1200px;
      margin: 0 auto;
      padding: 20px;
    }
    
    header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 40px;
    }
  </style>
</head>
<body>
  <header>
    <h1>My Documentation</h1>
    <div id="docsearch"></div>
  </header>
  
  <main>
    <h2>Welcome</h2>
    <p>Start searching by clicking the search button or pressing Ctrl+K.</p>
  </main>
  
  <!-- DocSearch JS -->
  <script src="https://cdn.jsdelivr.net/npm/@docsearch/js@4"></script>
  
  <script>
    docsearch({
      container: '#docsearch',
      appId: 'YOUR_APP_ID',
      apiKey: 'YOUR_SEARCH_API_KEY',
      indexName: 'YOUR_INDEX_NAME',
    });
  </script>
</body>
</html>
```

## Configuration Options

### Basic Configuration

The minimum required configuration:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
});
```

### Placeholder Text

Customize the search input placeholder:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  placeholder: 'Search documentation',
});
```

### Search Parameters

Add Algolia search parameters:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  searchParameters: {
    facetFilters: ['language:en', 'version:v2'],
    hitsPerPage: 20,
  },
});
```

### Transform Search Client

Modify the search client before queries:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  transformSearchClient: (searchClient) => {
    // Add custom agent
    searchClient.addAlgoliaAgent('my-site', '1.0.0');
    return searchClient;
  },
});
```

### Transform Items

Post-process search results:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  transformItems: (items) => {
    return items.map((item) => ({
      ...item,
      url: item.url.replace('https://old-domain.com', 'https://new-domain.com'),
    }));
  },
});
```

## Programmatic Control

The `docsearch()` function returns an instance with methods for programmatic control:

```js theme={null}
const instance = docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
});

// Open the modal programmatically
instance.open();

// Close the modal
instance.close();

// Check if modal is open
console.log(instance.isOpen); // true/false

// Check if component is ready
console.log(instance.isReady); // true/false

// Clean up when done
instance.destroy();
```

### Lifecycle Callbacks

Listen to lifecycle events:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  onReady: () => {
    console.log('DocSearch is ready');
  },
  onOpen: () => {
    console.log('Modal opened');
  },
  onClose: () => {
    console.log('Modal closed');
  },
});
```

## Ask AI Integration

### Basic Ask AI

Enable AI-powered conversational search:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  askAi: 'YOUR_ASSISTANT_ID',
});
```

### Ask AI with Configuration

Customize Ask AI behavior:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  askAi: {
    assistantId: 'YOUR_ASSISTANT_ID',
    appId: 'YOUR_APP_ID',
    apiKey: 'YOUR_SEARCH_API_KEY',
    indexName: 'YOUR_INDEX_NAME',
    suggestedQuestions: true,
  },
});
```

### Open Ask AI Programmatically

```js theme={null}
const instance = docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  askAi: 'YOUR_ASSISTANT_ID',
});

// Open Ask AI mode with a pre-filled question
instance.openAskAi({ query: 'How do I get started?' });
```

## Sidepanel Integration

For a better AI experience, use the sidepanel component:

<Steps>
  <Step title="Install sidepanel package">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @docsearch/sidepanel-js @docsearch/css
      ```

      ```bash yarn theme={null}
      yarn add @docsearch/sidepanel-js @docsearch/css
      ```
    </CodeGroup>

    Or use the CDN:

    ```html theme={null}
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@4/dist/sidepanel.css" />
    <script src="https://cdn.jsdelivr.net/npm/@docsearch/sidepanel-js@4"></script>
    ```
  </Step>

  <Step title="Add sidepanel container">
    ```html theme={null}
    <div id="docsearch"></div>
    <div id="docsearch-sidepanel"></div>
    ```
  </Step>

  <Step title="Initialize both components">
    ```js theme={null}
    import docsearch from '@docsearch/js';
    import sidepanel from '@docsearch/sidepanel-js';
    import '@docsearch/css/dist/style.css';
    import '@docsearch/css/dist/sidepanel.css';

    // Initialize sidepanel
    const sidepanelInstance = sidepanel({
      container: '#docsearch-sidepanel',
      appId: 'YOUR_APP_ID',
      apiKey: 'YOUR_SEARCH_API_KEY',
      indexName: 'YOUR_INDEX_NAME',
      assistantId: 'YOUR_ASSISTANT_ID',
    });

    // Initialize search and connect to sidepanel
    const searchInstance = docsearch({
      container: '#docsearch',
      appId: 'YOUR_APP_ID',
      apiKey: 'YOUR_SEARCH_API_KEY',
      indexName: 'YOUR_INDEX_NAME',
      askAi: 'YOUR_ASSISTANT_ID',
      interceptAskAiEvent: (initialMessage) => {
        searchInstance.close();
        sidepanelInstance.open(initialMessage);
        return true; // Prevent default Ask AI modal
      },
    });
    ```
  </Step>
</Steps>

## Custom Templates

Customize how results are rendered using the `hitComponent` and `resultsFooterComponent` options:

### Custom Hit Component

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  hitComponent: ({ hit, children }, { html }) => {
    return html`
      <a href="${hit.url}" class="custom-hit">
        <div class="hit-icon">📄</div>
        <div class="hit-content">
          ${children}
        </div>
      </a>
    `;
  },
});
```

### Custom Footer Component

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  resultsFooterComponent: ({ state }, { html }) => {
    const nbHits = state.context?.nbHits || 0;
    return html`
      <div class="custom-footer">
        <a href="/search?q=${state.query}">
          See all ${nbHits} results
        </a>
      </div>
    `;
  },
});
```

## Translations

Customize UI text:

```js theme={null}
docsearch({
  container: '#docsearch',
  appId: 'YOUR_APP_ID',
  apiKey: 'YOUR_SEARCH_API_KEY',
  indexName: 'YOUR_INDEX_NAME',
  translations: {
    button: {
      buttonText: 'Search',
      buttonAriaLabel: 'Search documentation',
    },
    modal: {
      searchBox: {
        resetButtonTitle: 'Clear query',
        cancelButtonText: 'Cancel',
      },
      startScreen: {
        recentSearchesTitle: 'Recent',
        noRecentSearchesText: 'No recent searches',
      },
      footer: {
        selectText: 'to select',
        navigateText: 'to navigate',
        closeText: 'to close',
      },
    },
  },
});
```

## Module Bundler Example

If you're using a bundler like Webpack, Vite, or Rollup:

```js title="main.js" theme={null}
import docsearch from '@docsearch/js';
import '@docsearch/css';

// Wait for DOM to be ready
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initSearch);
} else {
  initSearch();
}

function initSearch() {
  const instance = docsearch({
    container: '#docsearch',
    appId: 'YOUR_APP_ID',
    apiKey: 'YOUR_SEARCH_API_KEY',
    indexName: 'YOUR_INDEX_NAME',
    placeholder: 'Search docs',
    searchParameters: {
      facetFilters: ['language:en'],
    },
  });

  // Expose for debugging
  window.docsearch = instance;
}
```

## Styling

Customize DocSearch appearance with CSS:

```css title="custom.css" theme={null}
/* Customize the search button */
.DocSearch-Button {
  background-color: #f5f5f5;
  border-radius: 8px;
}

.DocSearch-Button:hover {
  background-color: #e0e0e0;
}

/* Customize the modal */
.DocSearch-Modal {
  --docsearch-primary-color: #5468ff;
  --docsearch-text-color: #1c1e21;
  --docsearch-spacing: 12px;
  --docsearch-modal-width: 600px;
}

/* Customize search results */
.DocSearch-Hit {
  padding: 8px;
}

.DocSearch-Hit-title {
  font-weight: 600;
}
```

## Complete Production Example

Here's a complete example with all best practices:

```html title="index.html" theme={null}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Documentation</title>
  
  <!-- Preconnect to Algolia -->
  <link rel="preconnect" href="https://YOUR_APP_ID-dsn.algolia.net" crossorigin="anonymous" />
  
  <!-- DocSearch CSS -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@4" />
  
  <style>
    /* Your custom styles */
  </style>
</head>
<body>
  <header>
    <h1>Documentation</h1>
    <div id="docsearch"></div>
  </header>
  
  <main>
    <!-- Your content -->
  </main>
  
  <!-- DocSearch JS -->
  <script src="https://cdn.jsdelivr.net/npm/@docsearch/js@4"></script>
  
  <script>
    (function() {
      'use strict';
      
      // Initialize when DOM is ready
      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
      } else {
        init();
      }
      
      function init() {
        var instance = docsearch({
          container: '#docsearch',
          appId: 'YOUR_APP_ID',
          apiKey: 'YOUR_SEARCH_API_KEY',
          indexName: 'YOUR_INDEX_NAME',
          placeholder: 'Search docs',
          searchParameters: {
            facetFilters: ['language:en']
          },
          onReady: function() {
            console.log('DocSearch ready');
          },
          transformSearchClient: function(searchClient) {
            searchClient.addAlgoliaAgent('my-site', '1.0.0');
            return searchClient;
          }
        });
        
        // Expose for debugging (optional)
        window.docsearch = instance;
      }
    })();
  </script>
</body>
</html>
```

## Troubleshooting

### Search button not appearing

1. Verify the container element exists: `document.querySelector('#docsearch')`
2. Check browser console for errors
3. Ensure DocSearch CSS is loaded
4. Verify you're calling `docsearch()` after DOM is ready

### Modal not opening

1. Check if JavaScript errors are preventing execution
2. Verify credentials are correct
3. Test keyboard shortcut (Ctrl+K) and button click separately

### No search results

1. Verify your index has data in Algolia dashboard
2. Check `searchParameters.facetFilters` aren't too restrictive
3. Test with a known indexed term
4. Check browser network tab for API errors

## Next Steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="code" href="/api/docsearch-js">
    Explore all configuration options
  </Card>

  <Card title="Styling" icon="palette" href="/concepts/styling">
    Customize the appearance of DocSearch
  </Card>

  <Card title="Ask AI" icon="sparkles" href="/concepts/ask-ai">
    Add AI-powered conversational search
  </Card>

  <Card title="React Integration" icon="react" href="/installation/react">
    Use DocSearch with React
  </Card>
</CardGroup>
