Flexsearch
Built-in document search of Fumadocs
Fumadocs supports searching document based on Flexsearch.
As the bulit-in search of Fumadocs, It is the default but also recommended option since it's easier to setup and totally free.
If you're using a CMS, you should use the API provided by the CMS instead.
Simple Search
Index with the raw content of document.
- Create the API Route.
import { createSearchAPI } from 'fumadocs-core/search/server';
export const { GET } = createSearchAPI('simple', {
indexes: allDocs.map((docs) => ({
title: docs.title,
content: docs.body.raw, // Raw Content
url: docs.url,
})),
});
- Create a Search Dialog.
import { useDocsSearch } from 'fumadocs-core/search/client';
export function Dialog() {
const { search, setSearch, query } = useDocsSearch();
return <div>...</div>;
}
createSearchAPI
Create a GET route handler, that supports simple
and advanced
search.
useDocsSearch
A hook that combined debounce value and useSWR
.
Return Type
Prop | Type | Description |
---|---|---|
query | SWRResponse | SWR Query |
search | string | Searching text (not debounced) |
setSearch | (v: string) => void | Set searching text |
Response Data
Type | |
---|---|
empty | If the searching text is empty or blank |
SortedResult[] | Array of matching pages, headings and contents. |
Internationalization
The default createSearchAPI
doesn't provide functionality for i18n. Instead,
you should use createI18nSearchAPI
.
- Update the route handler.
import { languages } from '@/i18n';
import { getPages } from '@/source';
import { createI18nSearchAPI } from 'fumadocs-core/search/server';
export const { GET } = createI18nSearchAPI('advanced', {
indexes: languages.map((lang) => {
const pages = getPages(lang)!.map((page) => ({
...
}));
return [lang, pages];
}),
});
- Add
locale
to search dialog, this will only allow pages with specified locale to be searched by the user.
function Dialog() {
const { search, setSearch, query } = useDocsSearch(locale);
//...
}
Advanced Search
Returns a more detailed result with matching headings and contents.
It accepts structured data procesed from a markdown/MDX document, and index it with Flexsearch. You can extract the structured data using the Structure remark plugin.
Notice that it cannot extract content from rehype-specific content (remark plugins are supported)
Usage
Same as simple search, but requires the structuredData
property.
import { allDocs } from 'contentlayer/generated';
import { createSearchAPI } from 'fumadocs-core/search/server';
export const { GET } = await createSearchAPI('advanced', {
indexes: allDocs.map((docs) => ({
id: docs._id,
title: docs.title,
url: '/docs/' + docs.slug,
structuredData: docs.structuredData,
})),
});
Tag Filter
It's useful for implementing versioned docs, or multi-docs similar to this documentation.
import { allDocs } from 'contentlayer/generated';
import { createSearchAPI } from 'fumadocs-core/search/server';
export const { GET } = createSearchAPI('advanced', {
indexes: allDocs.map((page) => ({
...page,
tag: 'value',
})),
tag: true,
});
// Pass `tag` in your custom search dialog
const { search, setSearch, query } = useDocsSearch(locale, tag);
Custom Algorithm
You can port your own search algorithm by returning a list of SortedResult
from your custom /api/search/route.ts
api endpoint, and you can integrate it
with Fumadocs UI later.
Last updated on 4/11/2024