Fumadocs

Trieve Search

Integrate Trieve Search with Fumadocs

This is a community maintained integration.

Introduction

The Trieve Integration automatically configures Trieve Search for site search.

By default, it creates a chunk for each paragraph in your document, it is officially recommended by Trieve.

Setup

Install Dependencies

npm install trieve-ts-sdk trieve-fumadocs-adapter

Sign up on Trieve

Sign up and create a dataset. Then obtain 2 API keys where one has only read access and the other has admin access to create and delete chunks. Store these credentials in environment variables.

Notice

One API Key should have only read access for the public facing search and the other should have admin access to create and delete chunks.

Sync Dataset

Export the search indexes by pre-rendering a static route.

lib/export-search-indexes.ts
import { source } from '@/lib/source';
import { type TrieveDocument } from 'trieve-fumadocs-adapter/search/sync';

export async function exportSearchIndexes() {
  const results: TrieveDocument[] = [];

  for (const page of source.getPages()) {
    results.push({
      _id: page.url,
      structured: page.data.structuredData,
      url: page.url,
      title: page.data.title,
      description: page.data.description,
    });
  }

  return results;
}
app/static.json/route.ts
import { exportSearchIndexes } from '@/lib/export-search-indexes';

export const revalidate = false;

export async function GET() {
  return Response.json(await exportSearchIndexes());
}

Create a script, the sync function will sync search indexes.

scripts/sync-content.ts
import * as fs from 'node:fs';
import { sync, type TrieveDocument } from 'trieve-fumadocs-adapter/search/sync';
import { TrieveSDK } from 'trieve-ts-sdk';

// the path of pre-rendered `static.json`, choose one according to your React framework
const filePath = {
  next: '.next/server/app/static.json.body',
  'tanstack-start': '.output/public/static.json',
  'react-router': 'build/client/static.json',
  waku: 'dist/public/static.json',
}['next'];

const content = fs.readFileSync(filePath);

const records: TrieveDocument[] = JSON.parse(content.toString());

const client = new TrieveSDK({
  apiKey: 'adminApiKey',
  datasetId: 'datasetId',
});

sync(client, records);

Make sure to run the script after build:

package.json
{
  "scripts": {
    "build": "... && bun scripts/sync-content.ts"
  }
}

You can also integrate it with your CI/CD pipeline.

Search UI

You can use their SearchDialog component:

components/search.tsx
'use client';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import SearchDialog from 'trieve-fumadocs-adapter/components/dialog/search';
import { TrieveSDK } from 'trieve-ts-sdk';

const trieveClient = new TrieveSDK({
  apiKey: 'readOnlyApiKey',
  datasetId: 'datasetId',
});

export default function CustomSearchDialog(props: SharedProps) {
  return <SearchDialog trieveClient={trieveClient} {...props} />;
}
  1. Replace apiKey and datasetId with your desired values.

  2. Replace the default search dialog with your new one.

Search Client

Add the useTrieveSearch hook:

import { TrieveSDK } from 'trieve-ts-sdk';
import { useTrieveSearch } from 'trieve-fumadocs-adapter/search/trieve';

const client = new TrieveSDK({
  apiKey: 'readOnlyApiKey',
  datasetId: 'datasetId',
});

const { search, setSearch, query } = useTrieveSearch(client);

Options

Tag Filter

To configure tag filtering, add a tag value to indexes.

import { sync } from 'trieve-fumadocs-adapter/search/sync';
import { TrieveSDK } from 'trieve-ts-sdk';

const client = new TrieveSDK({
  apiKey: 'adminApiKey',
  datasetId: 'datasetId',
});

const documents = records.map((index) => ({
  ...index,
  tag: 'value',
}));

sync(client, documents);

Search UI

Enable Tag Filter.

components/search.tsx
import SearchDialog from 'trieve-fumadocs-adapter/components/dialog/search';

<SearchDialog
  defaultTag="value"
  tags={[
    {
      name: 'Tag Name',
      value: 'value',
    },
  ]}
/>;

Search Client

The tag_set field is an attribute for filtering. To filter indexes by tag, use the filter on Trieve search clients.

{
  "must": [
    {
      "field": "tag_set",
      "match": ["value"]
    }
  ]
}

Or with useTrieveSearch hook:

import { TrieveSDK } from 'trieve-ts-sdk';
import { useTrieveSearch } from 'trieve-fumadocs-adapter/search/trieve';

const client = new TrieveSDK({
  apiKey: 'readOnlyApiKey',
  datasetId: 'datasetId',
});

const { search, setSearch, query } = useTrieveSearch(
  client,
  undefined,
  '<your tag value>',
);

How is this guide?

Last updated on