Fumadocs

内置搜索

Fumadocs 的内置文档搜索

Fumadocs 支持使用 Orama 进行文档搜索。它是默认选项,也是推荐选项,因为它可以自托管并且完全免费。

设置

托管处理搜索请求的服务器。

从源代码

从源对象创建服务器。

app/api/search/route.ts
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';

export const { GET } = createFromSource(source, {
  // https://docs.orama.com/docs/orama-js/supported-languages
  language: 'english',
});

从搜索索引

从搜索索引创建服务器,每个索引都需要一个 structuredData 字段。

通常,它由您的内容源提供(例如 Fumadocs MDX)。您也可以使用 Remark Structure 插件从 Markdown/MDX 文档中提取它。

app/api/search/route.ts
import { source } from '@/lib/source';
import { createSearchAPI } from 'fumadocs-core/search/server';

export const { GET } = createSearchAPI('advanced', {
  language: 'english',
  indexes: source.getPages().map((page) => ({
    title: page.data.title,
    description: page.data.description,
    url: page.url,
    id: page.url,
    structuredData: page.data.structuredData,
  })),
});

搜索文档

您可以使用以下方式搜索文档:

  • Fumadocs UI:开箱即用支持,详情请参阅 Search UI
  • Search Client
import {  } from 'fumadocs-core/search/client';

const  = ({
  : 'fetch',
});

Prop

Type

配置

标签过滤

支持按标签过滤结果,这对于实现类似于本文档的多文档站点非常有用。

import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';

const server = createFromSource(source, {
  buildIndex(page) {
    return {
      title: page.data.title,
      description: page.data.description,
      url: page.url,
      id: page.url,
      structuredData: page.data.structuredData,
      // 使用您想要的值,例如 page.slugs[0]
      tag: '<value>',
    };
  },
});

并更新您的搜索客户端:

  • Fumadocs UI:在 Search UI 上配置 Tag Filter
  • Search Client:向钩子传递一个标签。
import { useDocsSearch } from 'fumadocs-core/search/client';

const client = useDocsSearch({
  type: 'fetch',
  tag: '<value>',
});

静态模式

为了支持静态站点使用,请使用搜索服务器中的 staticGET,并使路由成为静态或预渲染的。

app/api/search/route.ts
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';

// 静态缓存
export const revalidate = false;
export const { staticGET: GET } = createFromSource(source);

staticGET 也在 createSearchAPI 中可用。

并更新您的搜索客户端:

  • Fumadocs UI:在 Search UI 上使用 static client

  • Search Client:使用 static 而非 fetch

    import { useDocsSearch } from 'fumadocs-core/search/client';
    
    const client = useDocsSearch({
      type: 'static',
    });

    Prop

    Type

小心

静态搜索要求客户端下载导出的搜索索引。 对于大型文档站点,这可能会很昂贵。

在这些情况下,您应该使用云解决方案,如 Orama Cloud 或 Algolia。

国际化

确保您的语言在 Orama Supported Languages 列表中。

app/api/search/route.ts
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';

const server = createFromSource(source, {
  localeMap: {
    // [locale]: Orama 选项
    ru: { language: 'russian' },
    en: { language: 'english' },
  },
});

对于 静态模式,您应该从客户端配置:

components/search.tsx
import { useDocsSearch } from 'fumadocs-core/search/client';
import { create } from '@orama/orama';

function initOrama(locale?: string) {
  return create({
    schema: { _: 'string' },
    language: locale === 'ru' ? 'russian' : 'english',
  });
}

function Search() {
  const client = useDocsSearch({
    type: 'static',
    initOrama,
  });

  // ...
}

特殊语言

中文和日文需要额外的配置:

npm i @orama/tokenizers
app/api/search/route.ts
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';
import { createTokenizer } from '@orama/tokenizers/mandarin';

export const { GET } = createFromSource(source, {
  localeMap: {
    // [locale]: Orama options
    cn: {
      components: {
        tokenizer: createTokenizer(),
      },
      search: {
        threshold: 0,
        tolerance: 0,
      },
    },
  },
});

并更新您的搜索客户端:

  • Fumadocs UI:无需更改,Fumadocs UI 在您正确配置 i18n 时会处理此问题。
  • Search Client: 将 locale 添加到搜索客户端,这将只允许具有指定区域设置的页面可被用户搜索。
import { useDocsSearch } from 'fumadocs-core/search/client';

const { search, setSearch, query } = useDocsSearch({
  type: 'fetch',
  locale: 'cn',
});

Headless

您可以将搜索服务器托管在其他后端上,例如 Express 和 Elysia。

import { initAdvancedSearch } from 'fumadocs-core/search/server';

const server = initAdvancedSearch({
  // 您仍然需要传递索引
});

server.search('query', {
  // 您可以在这里指定 `locale` 和 `tag`
});

How is this guide?

Last updated on