How can I implement a custom search in fumadocs?

dev
9f06196UI: fix `footer.children` props
This post might have stale content, as dev is 310 commits ahead.
Avatar of 0xKoller
Koller
posted

How can implement a custom search in fumadocs?

Avatar of anthropic/claude-haiku-4.5
Claude Haiku 4.5
commented

Perfect! Now I have a comprehensive understanding. Let me create a summary document for the user:

##How to Implement Custom Search in Fumadocs

Based on the source code, there are several ways to implement custom search in Fumadocs depending on your needs:

###1. Replace the Search Dialog UI (Simplest)

If you want to keep the built-in search functionality but customize the UI, you can provide a custom SearchDialog component to the RootProvider:

'use client';
import { RootProvider } from 'fumadocs-ui/provider/next';
import SearchDialog from '@/components/my-search-dialog';

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <RootProvider search={{ SearchDialog }}>
      {children}
    </RootProvider>
  );
}

The custom dialog must accept SharedProps:

'use client';
import { useDocsSearch } from 'fumadocs-core/search/client';
import {
  SearchDialog,
  SearchDialogClose,
  SearchDialogContent,
  SearchDialogHeader,
  SearchDialogIcon,
  SearchDialogInput,
  SearchDialogList,
  SearchDialogOverlay,
  type SharedProps,
} from 'fumadocs-ui/components/dialog/search';
import { useI18n } from 'fumadocs-ui/contexts/i18n';

export default function MySearchDialog(props: SharedProps) {
  const { locale } = useI18n();
  const { search, setSearch, query } = useDocsSearch({
    type: 'fetch', // or 'static'
    locale,
  });

  return (
    <SearchDialog search={search} onSearchChange={setSearch} isLoading={query.isLoading} {...props}>
      <SearchDialogOverlay />
      <SearchDialogContent>
        <SearchDialogHeader>
          <SearchDialogIcon />
          <SearchDialogInput />
          <SearchDialogClose />
        </SearchDialogHeader>
        <SearchDialogList items={query.data !== 'empty' ? query.data : null} />
      </SearchDialogContent>
    </SearchDialog>
  );
}

###2. Use Different Search Clients

Fumadocs supports multiple search backends via the useDocsSearch() hook:

Fetch (default - local API search):

const { search, setSearch, query } = useDocsSearch({
  type: 'fetch',
  api: '/api/search', // your search endpoint
  locale,
  tag, // optional tag filter
  delayMs: 100,
});

Algolia:

import { liteClient } from 'algoliasearch/lite';

const { search, setSearch, query } = useDocsSearch({
  type: 'algolia',
  indexName: 'your-index',
  client: liteClient('appId', 'searchKey'),
  tag,
  locale,
});

Orama Cloud:

const { search, setSearch, query } = useDocsSearch({
  type: 'orama-cloud',
  indexId: 'your-index-id',
  apiKey: 'your-api-key',
  tag,
});

Static (client-side only):

const { search, setSearch, query } = useDocsSearch({
  type: 'static',
  from: '/api/search', // exports the database
  tag,
});

Mixedbread:

const { search, setSearch, query } = useDocsSearch({
  type: 'mixedbread',
  apiKey: 'your-key',
  storeId: 'your-store',
});

###3. Completely Custom Search Implementation

If you need full control, create a custom component that doesn't use useDocsSearch:

'use client';
import { useState } from 'react';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';

export default function CustomSearchDialog({ open, onOpenChange }: SharedProps) {
  const [query, setQuery] = useState('');
  
  const handleSearch = async (q: string) => {
    // Your custom search logic here
    const results = await myCustomSearchFunction(q);
    return results;
  };

  return (
    <dialog open={open} onClose={() => onOpenChange(false)}>
      <input
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="Search..."
      />
      {/* Render your custom results */}
    </dialog>
  );
}

###4. Customize Search Server-Side (Backend)

For the API route, use createSearchAPI:

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

export const { GET, POST } = createFromSource(
  getPages(),
  {
    // Customize search options
    search: {
      // ... Orama search options
    },
  }
);

Or with advanced indexing:

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

export const GET = createSearchAPI('advanced', {
  indexes: async () => {
    return [
      {
        id: 'page-1',
        title: 'My Page',
        content: 'Page content...',
        url: '/docs/page-1',
        structuredData: { /* from MDX */ },
      },
    ];
  },
}).GET;

###5. Customize Hotkeys

<RootProvider
  search={{
    hotKey: [
      {
        display: 'S',
        key: 's',
      },
      {
        display: '⌘',
        key: (e) => e.metaKey || e.ctrlKey,
      },
    ],
  }}
>
  {children}
</RootProvider>

###6. Customize Search Dialog Options

<RootProvider
  search={{
    options: {
      links: [['Home', '/']],
      defaultTag: 'docs',
      tags: [
        { name: 'Docs', value: 'docs' },
        { name: 'API', value: 'api' },
      ],
      allowClear: true,
      delayMs: 200,
    },
  }}
>
  {children}
</RootProvider>

###Key Interfaces

  • SharedProps: { open: boolean; onOpenChange: (open: boolean) => void }
  • SortedResult: The search result type with id, type ('page', 'heading', 'text'), url, content, etc.
  • useDocsSearch return: { search: string; setSearch: (v: string) => void; query: { isLoading: boolean; data?: SortedResult[] | 'empty'; error?: Error } }

This gives you flexibility from simple UI customization to complete custom search implementations!

Avatar of 0xKoller
Koller
commented

What search clients do you recommend? give me a comparasion

Avatar of anthropic/claude-haiku-4.5
Claude Haiku 4.5
commented

Perfect! Now I have all the information needed. Let me create a comprehensive comparison:

##Search Clients Comparison for Fumadocs

Based on the source code and documentation, here's a detailed comparison of the search solutions supported by fumadocs:


###Pros:

  • Free & Self-hosted - No costs, fully open-source
  • Official recommendation - Fumadocs explicitly recommends this as default
  • No external dependencies - Keeps your data private
  • Easiest setup - Minimal configuration needed
  • Full-text & Vector search - Supports both search modes
  • Tag filtering - Built-in support for filtering
  • Multi-language support - Configurable language stemming
  • i18n friendly - Easy internationalization

###Cons:

  • Client-side indexing needed - Requires exporting database
  • Limited to your infra - Scales with your server capacity
  • No managed solution - You manage everything

###Setup Complexity: Easy

// From your source
import { createFromSource } from 'fumadocs-core/search/server';

export const { GET } = createFromSource(getPages());

###Cost: Free 💰

###Best For:

  • Small to medium docs sites
  • Privacy-conscious teams
  • Self-hosted deployments
  • Budget-conscious projects

##2. Algolia 🔍

###Pros:

  • Enterprise-grade - Mature, widely used platform
  • Excellent performance - Lightning-fast search at scale
  • Advanced features - Rich analytics, synonyms, custom ranking
  • Well-documented - Extensive guides and examples
  • Tag filtering - Good faceting support

###Cons:

  • Expensive - Complex pricing structure (costs can escalate)
  • Free tier limited - Requires logo display on free plan
  • External dependency - Vendor lock-in
  • Setup complexity - Requires syncing via scripts
  • Per-request billing - Costs grow with usage

###Setup Complexity: Medium ⭐⭐

// Need to sync docs regularly
import { sync } from 'fumadocs-core/search/algolia';
await sync(client, { indexName: 'docs', documents: records });

###Cost: $25+/month (variable based on usage) 💸

  • Starts around $25/month for build tier
  • Enterprise features require higher tiers
  • Per-search-request billing model

###Best For:

  • Large-scale doc sites
  • Enterprise requirements
  • Complex search features needed
  • Teams with budget

##3. Orama Cloud ☁️

###Pros:

  • Hosted solution - No server management needed
  • Two deployment options - REST API or Web Crawler
  • Easier than Algolia - Simpler pricing
  • Web crawler option - Auto-index without setup
  • Still from Orama team - Same company as default option

###Cons:

  • Requires signup - Not fully self-hosted
  • External dependency - Less control
  • Paid service - Not completely free
  • Sync script needed - Must run build scripts
  • Setup complexity - More configuration than local Orama

###Setup Complexity: Medium ⭐⭐

// Need credentials and sync
import { sync } from 'fumadocs-core/search/orama-cloud';
await sync(orama, { index, documents: records });

###Cost: Unknown (likely $0-15/month) 💰

  • No official pricing listed
  • Likely more affordable than Algolia
  • Free tier may be available

###Best For:

  • Teams wanting managed solution without full control
  • Those who prefer Orama but want hosting
  • Medium-scale documentation sites
  • Projects wanting balance of convenience and cost

###Pros:

  • Semantic/Vector search - Understands meaning, not just keywords
  • Natural language queries - Better UX for users
  • Modern approach - AI-powered search
  • Easy CLI - Simple sync with CLI tool
  • Simple setup - Fewer moving parts than Algolia

###Cons:

  • External service - Vendor lock-in
  • Requires API key - Third-party dependency
  • Paid service - Cost-based
  • Less mature - Fewer examples in wild
  • Different paradigm - Vector search may be overkill for docs

###Setup Complexity: Easy-Medium ⭐⭐

// Simple CLI-based sync
mxbai vs sync YOUR_STORE_ID "./content/docs" --ci

###Cost: Unknown (likely $10-30/month) 💰

  • Pricing not clearly listed in docs
  • Likely affordable compared to Algolia
  • Free tier possibility

###Best For:

  • Projects wanting advanced semantic search
  • Teams willing to use external services
  • Documentation with complex content
  • Users who value natural language search

##5. Trieve 🔗 (Community Maintained)

###Pros:

  • Open-source backend - Self-hosted option available
  • Modern approach - Designed for documentation
  • Community support - Active development
  • Flexible - Can self-host or use cloud

###Cons:

  • Community maintained - Not official support
  • Fewer examples - Less documentation
  • Admin credentials needed - Two API keys to manage
  • Newer project - Less battle-tested
  • Setup complexity - Requires more configuration

###Setup Complexity: Medium-Hard ⭐⭐⭐

// More complex sync process
import { sync } from 'trieve-fumadocs-adapter/search/sync';
sync(client, records);

###Cost: Unknown (likely free if self-hosted) 💰

  • Self-hosted option available
  • Cloud option pricing unknown
  • May be free or low-cost

###Best For:

  • Teams wanting to self-host
  • Those comfortable with community projects
  • Projects with specific Trieve requirements
  • Budget-conscious teams

##Quick Comparison Table

FeatureOramaAlgoliaOrama CloudMixedbreadTrieve
CostFree ⭐⭐⭐⭐⭐$25+/mo 🔴~$5-15/mo~$10-30/moFree (self-host)
SetupEasy ⭐⭐Medium ⭐⭐⭐Medium ⭐⭐⭐Easy ⭐⭐Hard ⭐⭐⭐⭐
Search QualityGood ⭐⭐⭐⭐Excellent ⭐⭐⭐⭐⭐Good ⭐⭐⭐⭐Excellent ⭐⭐⭐⭐⭐Good ⭐⭐⭐⭐
Vector SearchYesNoNoYes ⭐Yes
Self-hostedYes ⭐NoNoNoYes
MaintenanceYouVendorVendorVendorYou
ScalabilityMediumExcellentGoodGoodMedium
PrivacyBest ⭐LowMediumMediumBest ⭐
Official SupportYesYesYesLimitedNo
RecommendedYESFor enterpriseAlternativeModern UXAlternative

##Recommendation by Use Case

###📚 Small to Medium Docs Site

👉 Go with Orama (default)

  • Free, simple setup, no vendor lock-in
  • Perfect performance for your size
  • Keep it simple

###🚀 Large Enterprise Docs

👉 Algolia (if budget allows)

  • Best performance at scale
  • Advanced features
  • Proven reliability

👉 Mixedbread

  • Modern vector search
  • Better UX for complex queries
  • More natural language queries

###🏢 Self-hosted/Privacy Critical

👉 Orama or Trieve

  • Full control over data
  • No external dependencies
  • Better compliance

###Quick SaaS Solution

👉 Orama Cloud

  • Compromise between Orama and Algolia
  • Managed hosting without full control
  • Good balance

##My Personal Recommendation 🎯

Start with Orama (default) - It's:

  • The official recommendation
  • Completely free
  • Easy to set up
  • Good enough for most docs
  • No vendor lock-in

Upgrade to Algolia/Mixedbread only if:

  • You have specific advanced features needed
  • Cost is not a concern
  • You need enterprise support
  • You want semantic search (Mixedbread) or advanced analytics (Algolia)

The fumadocs team made the right choice making Orama the default!


END OF POST

How can I implement a custom search in fumadocs? — fuma-nama/fumadocs