Algolia Search
Integrate Algolia Search with Fumadocs
Notice
If you're using Algolia's free tier, you have to display their logo on your search dialog.
Introduction
The Algolia Integration automatically configures Algolia Search for document search.
It creates a record for each paragraph in your document, it is also recommended by Algolia.
Each record contains searchable attributes:
Attribute | Description |
---|---|
title | Page Title |
section | Heading ID (nullable) |
content | Paragraph content |
The section
field only exists in paragraphs under a heading. Headings and
paragraphs are indexed as an individual record, grouped by their page ID.
Notice that it expects the url
property of a page to be unique, you shouldn't have two pages with the same
url.
Setup
Install dependencies:
npm install algoliasearch
pnpm add algoliasearch
yarn add algoliasearch
bun add algoliasearch
Sign up on Algolia
Sign up and obtain the app id and API keys for your search. Store these credentials in environment variables.
Sync Search Indexes
Export the search indexes from Next.js using a route handler, this way we can access the search indexes after production build:
import { NextResponse } from 'next/server';
import { type DocumentRecord } from 'fumadocs-core/search/algolia';
import { source } from '@/lib/source';
export const revalidate = false;
export function GET() {
const results: DocumentRecord[] = [];
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 NextResponse.json(results);
}
Make a script to sync search indexes:
// @ts-check
import { algoliasearch } from 'algoliasearch';
import { sync } from 'fumadocs-core/search/algolia';
import * as fs from 'node:fs';
const content = fs.readFileSync('.next/server/app/static.json.body');
// now you can pass it to `sync`
/** @type {import('fumadocs-core/search/algolia').DocumentRecord[]} **/
const records = JSON.parse(content.toString());
const client = algoliasearch('id', 'key');
void sync(client, {
indexName: 'document',
documents: records,
});
The sync
function will update the index settings and sync search indexes.
Now run the script after build:
{
"scripts": {
"build": "next build && node ./update-index.mjs"
}
}
Workflow
You may make it a script and manually sync with node ./update-index.mjs
, or
integrate it with your CI/CD pipeline.
Typescript Usage
If you are running the script with TSX
or other similar Typescript executors, ensure to name it .mts
for best ESM
compatibility.
Search UI
You can consider different options for implementing the UI:
-
Using Fumadocs UI search dialog.
-
Build your own using the built-in search client hook:
import { liteClient } from 'algoliasearch/lite'; import { useDocsSearch } from 'fumadocs-core/search/client'; const client = liteClient('id', 'key'); const { search, setSearch, query } = useDocsSearch({ type: 'algolia', indexName: 'document', client, });
-
Use their official clients directly.
Options
Tag Filter
To configure tag filtering, add a tag
value to indexes.
import { sync } from 'fumadocs-core/search/algolia';
void sync(client, {
indexName: 'document',
documents: records.map((index) => ({
...index,
tag: 'value',
})),
});
And update your search client:
-
Fumadocs UI: Enable Tag Filter on Search UI.
-
Search Client: You can add the tag filter like:
import { useDocsSearch } from 'fumadocs-core/search/client'; const { search, setSearch, query } = useDocsSearch({ tag: '<your tag value>', // ... });
The tag
field is an attribute for faceting. You can also use the filter tag:value
on Algolia search clients.
How is this guide?
Last updated on