自定义搜索功能
在某些场景下,我们需要对搜索功能进行定制,比如:
- 对搜索过程中的关键词进行处理,比如去除敏感词
- 对默认的全文搜索结果进行过滤
- 对搜索关键字进行打点上报
- 自定义搜索数据源,比如从数据库中搜索
- 对自定义搜索数据源进行渲染
- ......
面对这些灵活的自定义需求,我们提供了相应的接口,对默认主题的搜索组件进行扩展,让你可以很容易地定制搜索功能。
searchHooks 概念和配置
在 Rspress 配置中,我们提供了 search.searchHooks
配置项,用于配置搜索组件的钩子函数,如下:
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
search: {
searchHooks: path.join(__dirname, './search.tsx'),
},
});
search.searchHooks
配置项的值为一个文件路径,这个文件会导出对应的钩子逻辑,如 onSearch
,从而让你可以定制搜索运行时的能力。我们可以称这个文件为 searchHooks
模块。
searchHooks 中的钩子函数
下面我们来介绍 searchHooks 中的钩子函数,即 beforeSearch
、onSearch
、afterRender
、render
。
在 searchHooks 模块中,你只需要导出你需要的钩子函数,而不是必须导出全部的钩子函数。
beforeSearch
beforeSearch
钩子函数会在搜索开始前执行,你可以用来对搜索关键字进行处理,比如去除敏感词,或者对搜索关键字进行打点上报。
该钩子支持异步操作。
使用示例如下:
import type { BeforeSearch } from '@rspress/core/theme';
const beforeSearch: BeforeSearch = (query: string) => {
// 可以在这里做一些搜索前的操作
console.log('beforeSearch');
// 返回处理后的 query
return query.replace(' ', '');
};
export { beforeSearch };
onSearch
onSearch
钩子函数会在默认的全文搜索逻辑完成之后执行,你可以在这个钩子函数中对搜索结果进行过滤或者上报,也可以在这个钩子函数中增加自定义的搜索数据源。
该钩子支持异步操作。
使用示例如下:
import type { OnSearch } from '@rspress/core/theme';
import { RenderType } from '@rspress/core/theme';
const onSearch: OnSearch = async (query, defaultSearchResult) => {
// 可根据 query 请求数据
console.log(query);
// 默认的搜索源的结果,为一个数组
console.log(defaultSearchResult);
// const customResult = await searchQuery(query);
// 可直接操作默认搜索结果
defaultSearchResult.pop();
// 返回值为一个数组,数组中的每一项为一个搜索源的结果,它们会被添加到搜索结果中
return [
{
group: 'Custom',
result: {
list: [
{
title: 'Search Result 1',
path: '/search1',
},
{
title: 'Search Result 2',
path: '/search2',
},
],
},
renderType: RenderType.Custom,
},
];
};
export { onSearch };
需要注意的是,onSearch
钩子函数的返回值为一个数组,数组中的每一项为一个搜索源的结果,每一项的结构如下:
{
group: string; // 搜索结果的分组名称,将会在搜索结果中显示
result: unknown;
renderType?: RenderType; // 搜索结果的渲染类型,支持 Default 和 Custom 两种类型。如果不填,默认取 RenderType.Custom
}
其中 result
为搜索结果,你可以自定义内部的结构。如果 renderType 为 RenderType.Default
,则会使用默认的渲染方式进行渲染,如果为 RenderType.Custom
,则会使用 render
钩子函数中的渲染方式进行渲染。
afterSearch
afterSearch
钩子函数会在搜索结果渲染完成之后执行,你可以在这个钩子拿到最终的搜索关键词和搜索结果。
该钩子支持异步操作。
使用示例如下:
import type { AfterSearch } from '@rspress/core/theme';
const afterSearch: AfterSearch = async (query, searchResult) => {
// 搜索关键词
console.log(query);
// 搜索结果
console.log(searchResult);
};
export { afterSearch };
render
render
函数会对你在 onSearch
钩子中自定义的搜索源数据进行渲染,因此一般需要和 onSearch
一起使用。使用方式如下:
import type { RenderSearchFunction } from '@rspress/core/theme';
// 上述的 OnSearch 钩子实现省略
interface ResultData {
list: {
title: string;
path: string;
}[];
}
// 针对每一个搜索源的渲染函数
const render: RenderSearchFunction<ResultData> = (item) => {
return (
<div>
{item.list.map((i) => (
<div>
<a href={i.path}>{i.title}</a>
</div>
))}
</div>
);
};
export { onSearch, render };
效果如下: