Search
Set up the search dialog of your site.
Search works without setup, with FlexSearch. The build exports an index of your pages, and the browser downloads and searches it. With a dynamic source, like Notion, search runs on your server instead, since the pages change after the build.
Search Engines
FlexSearch is the default, and search of recommendedPreset() takes its options, like in Customization. To use another engine, set search: false and add the plugin of the engine. Without one, the site has no search:
import { createPress, recommendedPreset } from "@fumapress/astro/config";
import { oramaSearchPlugin } from "@fumapress/astro/plugins/orama-search";
export const app = createPress(content).plugins(oramaSearchPlugin());
export default app.config({
preset: recommendedPreset({ search: false }),
});An engine like Algolia is a separate plugin. See Custom Search Engine.
Customization
These options work with both FlexSearch and Orama.
Server-Side Search
On a large site, the index is a big download for every reader. To keep the index on the server, set the render option of the search plugin. The site then needs a server.
createPress(content).config({
preset: recommendedPreset({ search: { render: "dynamic" } }),
});Search Index
The index contains the headings and text of each page, from your content source. Pages without headings and text are searched by title.
Both plugins take buildIndex to change the fields. The result must include structuredData, the headings and text. This example adds a tag to each page, so that a dialog can filter by it:
recommendedPreset({
search: {
async buildIndex(page) {
const data = await this.getPageStructuredData(page);
return {
id: page.url,
title: page.data.title ?? page.path,
description: page.data.description,
url: page.url,
structuredData: data ?? { headings: [], contents: [] },
tag: page.path.split("/")[0],
};
},
},
});Search results show the same breadcrumb as the page. To change it, return breadcrumbs from buildIndex.
Custom Search Dialog
Compose a dialog from the parts of Fumadocs UI and a search hook, then pass it through ui.providerProps. The dialog receives the options of the search plugin as props.
"use client";
import {
useFlexsearchStatic,
type FlexsearchStaticOptions,
} from "fumadocs-core/search/client/flexsearch-static";
import {
SearchDialog as Dialog,
SearchDialogContent,
SearchDialogHeader,
SearchDialogInput,
SearchDialogList,
SearchDialogOverlay,
type SharedProps,
} from "fumadocs-ui/components/dialog/search";
type Props = SharedProps & FlexsearchStaticOptions;
export function SearchDialog({ from, locale, ...props }: Props) {
return (
<Dialog {...props} {...useFlexsearchStatic({ from, locale, tag: "guides" })}>
<SearchDialogOverlay />
<SearchDialogContent>
<SearchDialogHeader>
<SearchDialogInput />
</SearchDialogHeader>
<SearchDialogList />
</SearchDialogContent>
</Dialog>
);
}When search runs on the server, the props are api and locale, and the hook is useFetchSearch from fumadocs-core/search/client/fetch.
Last updated on