---
title: Search
description: Implement document search in your docs
image: /images/blog/post-6.png
date: "2025-02-15T12:00:00.000Z"
published: true
categories: [company, news]
author: mksaas
---

Fumadocs UI provides a good-looking search UI for your docs, the search functionality is instead provided and documented on Fumadocs Core.

See [Document Search](/docs/headless/search).

## Search UI

Open with <kbd>⌘</kbd> <kbd>K</kbd> or <kbd>Ctrl</kbd> <kbd>K</kbd>.

### Configurations

You can customize search UI from the [Root Provider](/docs/layouts/root-provider) component in root layout.

When not specified, it uses the Default [`fetch` Search Client](/docs/headless/search/orama) powered by Orama.

### Custom Links

Add custom link items to search dialog.
They are shown as fallbacks when the query is empty.

```tsx title="app/layout.tsx"
import { RootProvider } from 'fumadocs-ui/root-provider';

<RootProvider
  search={{
    links: [
      ['Home', '/'],
      ['Docs', '/docs'],
    ],
  }}
>
  {children}
</RootProvider>;
```

### Disable Search

To opt-out of document search, disable it from root provider.

```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';

<RootProvider
  search={{
    enabled: false,
  }}
>
  {children}
</RootProvider>;
```

### Hot Keys

Customise the hot keys to trigger search dialog.

```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';

<RootProvider
  search={{
    hotKey: [
      {
        display: 'K',
        key: 'k', // key code, or a function determining whether the key is pressed
      },
    ],
  }}
>
  {children}
</RootProvider>;
```

### Tag Filter

Add UI to change filters.
Make sure to configure [Tag Filter](/docs/headless/search/orama#tag-filter) on search server first.

```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';

<RootProvider
  search={{
    options: {
      defaultTag: 'value',
      tags: [
        {
          name: 'Tag Name',
          value: 'value',
        },
      ],
    },
  }}
>
  {children}
</RootProvider>;
```

### Search Options

Pass options to the search client, like changing the API endpoint for Orama search server:

```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';

<RootProvider
  search={{
    options: {
      api: '/api/search/docs',
    },
  }}
>
  {children}
</RootProvider>;
```

### Replace Search Dialog

You can replace the default Search Dialog with:

```tsx title="components/search.tsx"
'use client';
import SearchDialog from 'fumadocs-ui/components/dialog/search-default';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';

export default function CustomDialog(props: SharedProps) {
  // your own logic here
  return <SearchDialog {...props} />;
}
```

To pass it to the Root Provider, you need a wrapper with `use client` directive.

```tsx title="provider.tsx"
'use client';
import { RootProvider } from 'fumadocs-ui/provider';
import dynamic from 'next/dynamic';
import type { ReactNode } from 'react';

const SearchDialog = dynamic(() => import('@/components/search')); // lazy load

export function Provider({ children }: { children: ReactNode }) {
  return (
    <RootProvider
      search={{
        SearchDialog,
      }}
    >
      {children}
    </RootProvider>
  );
}
```

Use it instead of your previous Root Provider

```tsx title="layout.tsx"
import { Provider } from './provider';
import type { ReactNode } from 'react';

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Provider>{children}</Provider>
      </body>
    </html>
  );
}
```

## Other Solutions

### Algolia

For the setup guide, see [Integrate Algolia Search](/docs/headless/search/algolia).

While generally we recommend building your own search with their client-side
SDK, you can also plug the built-in dialog interface.

```tsx title="components/search.tsx"
'use client';
import algo from 'algoliasearch/lite';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import SearchDialog from 'fumadocs-ui/components/dialog/search-algolia';

const client = algo('appId', 'apiKey');
const index = client.initIndex('indexName');

export default function CustomSearchDialog(props: SharedProps) {
  return <SearchDialog index={index} {...props} />;
}
```

1. Replace `appId`, `apiKey` and `indexName` with your desired values.

2. [Replace the default search dialog](#replace-search-dialog) with your new component.

<Callout title="Note" className='mt-4'>

    The built-in implementation doesn't use instant search (their official
    javascript client).

</Callout>

#### Tag Filter

Same as default search client, you can configure [Tag Filter](/docs/headless/search/algolia#tag-filter) on the dialog.

```tsx title="components/search.tsx"
import SearchDialog from 'fumadocs-ui/components/dialog/search-algolia';

<SearchDialog
  defaultTag="value"
  tags={[
    {
      name: 'Tag Name',
      value: 'value',
    },
  ]}
/>;
```

### Orama Cloud

For the setup guide, see [Integrate Orama Cloud](/docs/headless/search/orama-cloud).

```tsx title="components/search.tsx"
'use client';

import { OramaClient } from '@oramacloud/client';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import SearchDialog from 'fumadocs-ui/components/dialog/search-orama';

const client = new OramaClient({
  endpoint: 'endpoint',
  api_key: 'apiKey',
});

export default function CustomSearchDialog(props: SharedProps) {
  return <SearchDialog {...props} client={client} showOrama />;
}
```

1. Replace `endpoint`, `apiKey` with your desired values.
2. [Replace the default search dialog](#replace-search-dialog) with your new component.

### Community Integrations

A list of integrations maintained by community.

- [Trieve Search](/docs/headless/search/trieve)

## Built-in UI

If you want to use the built-in search dialog UI instead of building your own,
you may use the `SearchDialog` component.

```tsx
import {
  SearchDialog,
  type SharedProps,
} from 'fumadocs-ui/components/dialog/search';

export default function CustomSearchDialog(props: SharedProps) {
  return <SearchDialog {...props} />;
}
```

<Callout type="warn" title="Unstable">
  It is an internal API, might break during iterations
</Callout>
