Customize search functions
In some scenarios, we need to customize the search function, such as:
- Processing keywords in the search process, such as removing sensitive words.
- Filtering the default full-text search results.
- Reporting the search keywords.
- Customizing the search data source, such as searching from the database.
- Rendering the custom search data source.
- ......
Faced with these flexible custom requirements, we provide corresponding interfaces to extend the search components of the default theme, making it easy for you to customize the search function.
Understanding searchHooks
In the Rspress config, we provide a search.searchHooks
config item for configuring the hook functions of the search components, as follows:
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
search: {
searchHooks: path.join(__dirname, './search.tsx'),
},
});
The value of the search.searchHooks
config item is a file path. This file will export the corresponding hook logic, such as onSearch
, so that you can customize the capabilities of the search at run time. We can call this file a searchHooks
module.
Hook functions in searchHooks
Next, let us introduce the hook functions in searchHooks, namely beforeSearch
, onSearch
, afterRender
and render
.
TIP
In the searchHooks module, you only need to export the hook functions you need, instead of necessarily exporting all the hook functions.
beforeSearch
The beforeSearch
hook function will be executed before the search starts, you can use it to process the search keywords, such as removing sensitive words, or reporting the search keywords.
This hook supports asynchronous operations.
Here is an example of usage:
import type { BeforeSearch } from '@rspress/core/theme';
const beforeSearch: BeforeSearch = (query: string) => {
// Some operations before search can be done here
console.log('beforeSearch');
// Return the processed query
return query.replace(' ', '');
};
export { beforeSearch };
onSearch
The onSearch
hook function will be executed after the default full-text search logic is finished. You can use this hook function to filter or report the search results, or you can add a custom search data source in this hook function.
This hook supports asynchronous operations.
Here is an example of how to use it:
import type { OnSearch } from '@rspress/core/theme';
import { RenderType } from '@rspress/core/theme';
const onSearch: OnSearch = async (query, defaultSearchResult) => {
// Can request data based on query
console.log(query);
// The results of the default search source, which is an array
console.log(defaultSearchResult);
// const customResult = await searchQuery(query);
// Can directly operate the default search results.
defaultSearchResult.pop();
// The return value is an array, each item in the array is a search source result, and they will be added to the search result
return [
{
group: 'Custom',
result: {
list: [
{
title: 'Search Result 1',
path: '/search1',
},
{
title: 'Search Result 2',
path: '/search2',
},
],
},
renderType: RenderType.Custom,
},
];
};
export { onSearch };
Note that the return value of the onSearch
hook function is an array, each item in the array is a search source result, and each item has the following structure:
{
group: string; // The group name of the search result, which will be displayed in the search results.
result: unknown;
renderType: RenderType; // The type of the search result, which can be `RenderType.Default` or `RenderType.Custom`. `RenderType.custom` by default.
}
The result
is the search result, you can customize its internal structure. The renderType
is the type of the search result, which can be RenderType.Default
or RenderType.Custom
. If it is RenderType.Default
, the default search result rendering logic will be used; if it is RenderType.Custom
, the render
function will be used to render the search result.
afterSearch
The afterSearch
hook function will be executed after the search result is rendered. You can get the final search keywords and search results in this hook.
This hook supports asynchronous operations.
Here is an example of usage:
import type { AfterSearch } from '@rspress/core/theme';
const afterSearch: AfterSearch = async (query, searchResult) => {
// Search keyword
console.log(query);
// Search result
console.log(searchResult);
};
export { afterSearch };
render
The render
function will render the custom search source data in your onSearch
hook. Therefore, it generally needs to be used together with onSearch
. Here's how to use it:
import type { RenderSearchFunction } from '@rspress/core/theme';
// The above OnSearch hook implementation is skipped
interface ResultData {
list: {
title: string;
path: string;
}[];
}
// The render function for each search source
const render: RenderSearchFunction<ResultData> = item => {
return (
<div>
{item.list.map(i => (
<div>
<a href={i.path}>{i.title}</a>
</div>
))}
</div>
);
};
export { onSearch, render };
The result is as follows:
