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

Далее разберём доступные хуки: beforeSearch, onSearch, afterRender и render.

Совет

В модуле searchHooks достаточно экспортировать только те хуки, которые вам действительно нужны — экспортировать все сразу не требуется.

beforeSearch

Хук beforeSearch выполняется до начала поиска. Его удобно использовать для предварительной обработки поискового запроса, например, удаления запрещённых слов или отправки отчёта о введённом запросе.

Хук поддерживает асинхронные операции.

Пример использования:

import type { BeforeSearch } from '@rspress/core/theme';

const beforeSearch: BeforeSearch = (query: string) => {
  // Выполняем какие-то операции перед поиском
  console.log('beforeSearch');
  // Возвращаем обработанный запрос
  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) => {
  // Можно делать запрос данных по запросу пользователя
  console.log(query);
  // Результаты стандартного источника поиска — это массив
  console.log(defaultSearchResult);
  // const customResult = await searchQuery(query);

  // Можно напрямую модифицировать результаты стандартного поиска
  defaultSearchResult.pop();

  // Возвращаемое значение — массив. Каждый элемент массива считается результатом от отдельного источника поиска
  // и будет добавлен в общий список результатов
  return [
    {
      group: 'Custom',
      result: {
        list: [
          {
            title: 'Результат поиска 1',
            path: '/search1',
          },
          {
            title: 'Результат поиска 2',
            path: '/search2',
          },
        ],
      },
      renderType: RenderType.Custom,
    },
  ];
};

export { onSearch };

Обратите внимание: возвращаемое значение хука onSearch — это массив. Каждый элемент массива представляет результат от отдельного источника поиска и имеет следующую структуру:

{
  group: string; // Название группы результатов поиска, которое будет отображаться в интерфейсе
  result: unknown;
  renderType: RenderType; // Тип результата поиска. Может быть `RenderType.Default` или `RenderType.Custom`. По умолчанию — `RenderType.Custom`.
}

Поле result — это сами результаты поиска, вы можете задавать для него любую удобную вам внутреннюю структуру. Поле renderType определяет тип результата и может принимать значения RenderType.Default или RenderType.Custom:

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

Вот как выглядит результат:

Оформление результатов поиска