Fumadocs

Search UI

The UI for document search

Overview

You can customize Search UI from <RootProvider />.

app/layout.tsx
import { RootProvider } from 'fumadocs-ui/provider/<framework>';
import type { ReactNode } from 'react';
import { SearchDialog } from '@/components/my-search-dialog';

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <html>
      <body>
        <RootProvider
          search={{
            enabled: false, // disable search entirely
            SearchDialog, // replace search dialog
          }}
        >
          {children}
        </RootProvider>
      </body>
    </html>
  );
}

Hot Keys

Customize the hot keys to trigger search dialog, by default it's ⌘ K or Ctrl K.

import { RootProvider } from 'fumadocs-ui/provider/<framework>';

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

References

A full list of options.

Prop

Type

Custom UI

Fumadocs UI also exposes a lower level <SearchDialog /> component for advanced use, you can create your own search dialog to replace the default one.

'use client';
import React from 'react';
import {  } from 'fumadocs-core/search/client';
import {
  ,
  ,
  ,
  ,
  ,
  ,
  ,
  ,
  ,
  type SharedProps,
} from 'fumadocs-ui/components/dialog/search';
import {  } from 'fumadocs-ui/contexts/i18n';

export default function (: SharedProps) {
  const {  } = (); // (optional) for i18n
  const  = ({
    ,
  });

  return (
    < {...} {...}>
      < />
      <>
        <>
          < />
          < />
          < />
        </>
        < />
      </>
      <>{/* footer items */}</>
    </>
  );
}

Content Renderer

To render the Markdown content of search items on your own instead, pass renderMarkdown.

components/search.tsx
<SearchDialogList
  Item={(props) => (
    <SearchDialogListItem
      {...props}
      renderMarkdown={(text) => {
        // ...
      }}
    />
  )}
/>

Tables

Customize how tables in results are rendered. A custom Table renders the rows on its own:

components/search.tsx
<SearchDialogList
  // show the rows without a card
  Table={({ table, Item, onSelect }) =>
    table.rows.map((row) => (
      <Fragment key={row.id}>{Item({ item: row, onClick: () => onSelect(row) })}</Fragment>
    ))
  }
/>

Highlights

Matches of the search query are highlighted with the CSS Custom Highlight API, style them with ::highlight(fd-search).

global.css
::highlight(fd-search) {
  color: var(--color-fd-primary-foreground);
  background-color: var(--color-fd-primary);
}

<SearchDialogList /> highlights the query of data from <SearchDialog />, or the search input without it.

When rendering results on your own, highlight them with useHighlightQuery().

components/search-result.tsx
'use client';
import { useHighlightQuery } from 'fumadocs-core/search/client';
import type { ReactNode } from 'react';

export function SearchResult({ query, children }: { query: string; children: ReactNode }) {
  const ref = useHighlightQuery(query);

  return <div ref={ref}>{children}</div>;
}

Text inside elements with data-highlight-ignore is not highlighted, like the badges of components.

How is this guide?

Last updated on