How can I implement a custom search in fumadocs?
How can implement a custom search in fumadocs?
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 withid,type('page', 'heading', 'text'),url,content, etc.useDocsSearchreturn:{ 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!
What search clients do you recommend? give me a comparasion
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:
##1. Orama (Built-in/Default) ⭐ Recommended
###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
##4. Mixedbread 🤖 (Vector Search)
###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
| Feature | Orama | Algolia | Orama Cloud | Mixedbread | Trieve |
|---|---|---|---|---|---|
| Cost | Free ⭐⭐⭐⭐⭐ | $25+/mo 🔴 | ~$5-15/mo | ~$10-30/mo | Free (self-host) |
| Setup | Easy ⭐⭐ | Medium ⭐⭐⭐ | Medium ⭐⭐⭐ | Easy ⭐⭐ | Hard ⭐⭐⭐⭐ |
| Search Quality | Good ⭐⭐⭐⭐ | Excellent ⭐⭐⭐⭐⭐ | Good ⭐⭐⭐⭐ | Excellent ⭐⭐⭐⭐⭐ | Good ⭐⭐⭐⭐ |
| Vector Search | Yes | No | No | Yes ⭐ | Yes |
| Self-hosted | Yes ⭐ | No | No | No | Yes |
| Maintenance | You | Vendor | Vendor | Vendor | You |
| Scalability | Medium | Excellent | Good | Good | Medium |
| Privacy | Best ⭐ | Low | Medium | Medium | Best ⭐ |
| Official Support | Yes | Yes | Yes | Limited | No |
| Recommended | YES ✅ | For enterprise | Alternative | Modern UX | Alternative |
##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
###💡 Want Semantic/AI Search
👉 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