Typesense 検索
Typesense 検索を Fumadocs に統合します
これはコミュニティによってメンテナンスされているインテグレーションです。
セットアップ
依存関係のインストール
npm install typesense typesense-fumadocs-adapterTypesense サーバーを起動する
Typesense サーバーは、セルフホストすることも、Typesense のクラウドサービスを利用することもできます。公式のスタートガイドに従ってサーバーをセットアップし、認証情報を .env.local に保存してください (NEXT_PUBLIC_ は、Vite 系フレームワークでは VITE_、Astro では PUBLIC_ に置き換えてください) 。
NEXT_PUBLIC_TYPESENSE_URL="server URL"
NEXT_PUBLIC_TYPESENSE_SEARCH_KEY="search-only API key"
TYPESENSE_API_KEY="API key with write access"データセットの同期
事前レンダリングした static.json ルートで検索インデックスをエクスポートし、ビルドのたびにスクリプトで Typesense に同期します。
import { source } from '@/lib/source';
import type { DocumentRecord } from 'typesense-fumadocs-adapter';
async function getDocuments() {
const documents: DocumentRecord[] = [];
for (const page of source.getPages()) {
documents.push({
_id: page.url,
structured: page.data.structuredData,
url: page.url,
title: page.data.title,
description: page.data.description,
locale: page.locale,
});
}
return documents;
}
export const revalidate = false;
export async function GET() {
return Response.json(await getDocuments());
}
import * as fs from 'node:fs/promises';
import { type DocumentRecord, sync } from 'typesense-fumadocs-adapter';
import { Client } from 'typesense';
// Next.js writes it under `route-cache` when built with an adapter, like on Vercel
const [file] = await Array.fromAsync(fs.glob('.next/server/{app,route-cache/*/*/$}/static.json.body'));
const records = JSON.parse(await fs.readFile(file, 'utf-8')) as DocumentRecord[];
const client = new Client({
nodes: [{ url: process.env.NEXT_PUBLIC_TYPESENSE_URL! }],
apiKey: process.env.TYPESENSE_API_KEY!,
connectionTimeoutSeconds: 60 * 15,
});
await sync(client, {
typesenseCollectionName: 'docs',
documents: records,
});
console.log(`search updated: ${records.length} records`);
{
"scripts": {
"build": "next build && node --env-file-if-exists=.env.local scripts/sync-content.ts"
}
}build スクリプトはビルドのたびに同期を実行するため、デプロイ先のプラットフォームにも同じ環境変数を設定してください。
検索 UI
検索 UI は、次のいずれかの方法で実装できます。
-
Fumadocs UI の検索ダイアログを使用する。
-
Typesense の検索クライアントフックを使って、独自の検索 UI を構築する。
import { Client } from 'typesense'; import { useTypesenseSearch } from 'typesense-fumadocs-adapter/client'; const client = new Client({ nodes: [{ url: 'YOUR_TYPESENSE_SERVER_URL' }], apiKey: 'YOUR_TYPESENSE_SEARCH_ONLY_API_KEY', }); const { search, setSearch, query } = useTypesenseSearch({ typesenseCollectionName: 'docs', client, });
オプション
タグフィルター
タグフィルターを設定するには、static.json ルートで返すドキュメントに tag の値を追加します。
documents.push({
// その他のフィールド…
tag: '<your value>',
});次に、検索クライアントを更新します。
-
Fumadocs UI: 検索 UI でタグフィルターを有効にします。
-
検索クライアント: 次のようにタグフィルターを追加できます。
import { useTypesenseSearch } from 'typesense-fumadocs-adapter/client'; const { search, setSearch, query } = useTypesenseSearch({ tag: '<your tag value>', // ... });
国際化 (i18n)
ドキュメントにはページの locale が含まれているため、検索クライアントにも locale を渡してください。
import { useI18n } from 'fumadocs-ui/contexts/i18n';
import { useTypesenseSearch } from 'typesense-fumadocs-adapter/client';
const { locale } = useI18n();
const { search, setSearch, query } = useTypesenseSearch({
locale,
// その他のフィールド…
});内部的には、Typesense はロケールごとに個別のコレクションを作成します。コレクション名の末尾には _{locale} サフィックスが付加されます (例:docs_en、docs_fr) 。
How is this guide?
最終更新日
