close
  • 中文
  • 自定义搜索

    在某些场景下,我们需要对搜索功能进行定制,比如:

    • 对搜索过程中的关键词进行处理,比如去除敏感词
    • 对默认的全文搜索结果进行过滤
    • 对搜索关键字进行打点上报
    • 自定义搜索数据源,比如从数据库中搜索
    • 对自定义搜索数据源进行渲染
    • ......

    面对这些灵活的自定义需求,我们提供了相应的接口,对默认主题的搜索组件进行扩展,让你可以很容易地定制搜索功能。

    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 中的钩子函数,即 beforeSearchonSearchafterRenderrender

    提示

    在 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 };

    效果如下:

    自定义搜索源渲染