Skip to main content
ESC

Search

You can configure search in two ways: by providing the path to the search API route or by supplying a callback with custom search logic.

API Route 

To use an API route for search, pass the path to the search endpoint in the searcher prop of the Header component. The search API should return an array of results with the following keys:

Here’s an example of how to configure the Header component with a search API route:

TypeScript
JavaScript
import { RobinProvider, Header } from "robindoc";

const Layout: React.FC<React.PropsWithChildren> = ({ children }) => (
<RobinProvider>
<Header logo={<Logo />} searcher="/api/search" />
{/* ... */}
</RobinProvider>
);
import { RobinProvider, Header } from "robindoc";

const Layout = ({ children }) => (
<RobinProvider>
<Header logo={<Logo />} searcher="/api/search" />
{/* ... */}
</RobinProvider>
);

Client-Side Callback 

If you prefer to handle search logic entirely on the client side, you can provide an asynchronous callback function to the searcher prop. This function will be called with the search query and an AbortController and should return an array of search results.

Here’s an example callback function:

TypeScript
JavaScript
import { type Searcher } from "robindoc/lib/core/types/search";

export const searcher: Searcher = async (search, abortController) => {
const results = await advancedSearcher(pagesData, search, abortController);
return results;
};
export const searcher = async (search, abortController) => {
const results = await advancedSearcher(pagesData, search, abortController);
return results;
};

API Route Example 

If you use an API route, the server should handle the search requests. The following code demonstrates a simple search implementation using the match-sorter library and the utilities getStaticParams and getPageData:

TypeScript
JavaScript
import { matchSorter } from "match-sorter";
import { getStaticParams, getPageData } from "../docs/robindoc";

export const GET = async (request: Request) => {
const url = new URL(request.url);
const search = url.searchParams.get("s");

const headers = new Headers();
headers.set("Content-Type", "application/json; charset=UTF-8");

if (!search) return new Response(JSON.stringify([]), { headers });

const staticParams = await getStaticParams();
const docs: { href: string; raw: string; title: string }[] = [];

for await (const staticParam of staticParams) {
const pathname = `/${staticParam.segments.join("/")}`;
const { raw, title } = await getPageData(pathname);
docs.push({ href: pathname, raw, title });
}

const matchResults = matchSorter(docs, search, {
keys: ["raw", "title"],
});
const searchResults = matchResults
.slice(0, 5)
.map((item) => ({ title: item.title, href: item.href }));

return new Response(JSON.stringify(searchResults), { headers });
};
import { matchSorter } from "match-sorter";
import { getStaticParams, getPageData } from "../docs/robindoc";

export const GET = async (request) => {
const url = new URL(request.url);
const search = url.searchParams.get("s");

const headers = new Headers();
headers.set("Content-Type", "application/json; charset=UTF-8");

if (!search) return new Response(JSON.stringify([]), { headers });

const staticParams = await getStaticParams();
const docs = [];

for await (const staticParam of staticParams) {
const pathname = `/${staticParam.segments.join("/")}`;
const { raw, title } = await getPageData(pathname);
docs.push({ href: pathname, raw, title });
}

const matchResults = matchSorter(docs, search, {
keys: ["raw", "title"],
});
const searchResults = matchResults
.slice(0, 5)
.map((item) => ({ title: item.title, href: item.href }));

return new Response(JSON.stringify(searchResults), { headers });
};

For more information about configuring search, refer to the page on App Organization.

Previous
Internationalization
Next
Theming
Return to navigation