Skip to main content

Algolia DocSearch

This article guides you through adding Algolia Search to Docusaurus v3, assuming you already have an active Algolia account.

Default​

Add the following Algolia search configuration:

localhost
docusaurus.config.js
module.exports = {
...
algolia: {
apiKey: 'YOUR_API_KEY',
indexName: 'YOUR_INDEX_NAME',
appId: 'YOUR_APP_ID',
},
...
};

Custom​

In this method, we will extend Algolia search React component by utilizing the Swizzle method:

Add the following on your site configuration:

localhost
docusaurus.config.ts
import type { Config } from "@docusaurus/types";
import type * as Preset from "@docusaurus/preset-classic";

const config: Config = {
title: "My Site",
favicon: "img/favicon.ico",


scripts: [
{
src: "https://YOUR_APP_ID-dsn.algolia.net",
rel: "preconnect",
crossorigin: true,
},
],


/* Your site config here */
};

export default config;

JavaScript

npm run swizzle @docusaurus/theme-classic SearchBar

Typescript

npm run swizzle @docusaurus/theme-classic SearchBar --typescript

Choose the --wrap option and add the following configuration in your src/theme/SearchBar:

localhost
src/theme/SearchBar.js
import React from "react";
import SearchBar from "@theme-original/SearchBar";
import type SearchBarType from "@theme/SearchBar";
import type { WrapperProps } from "@docusaurus/types";
import { DocSearch } from "@docsearch/react";


export default function SearchBarWrapper(props) {
return (
<div>
<DocSearch
appId="YOUR_APP_ID"
indexName="YOUR_INDEX_NAME"
apiKey="YOUR_API_KEY"
/>
</div>
);
}
tip

Visit documentation to learn more.

Crawlers​

Docusaurus highly recommends to use the official v3 crawler configuration.

Crawlers template
new Crawler({
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_API_KEY',
rateLimit: 8,
maxDepth: 10,
startUrls: ['https://YOUR_WEBSITE_URL/'],
sitemaps: ['https://YOUR_WEBSITE_URL/sitemap.xml'],
ignoreCanonicalTo: true,
discoveryPatterns: ['https://YOUR_WEBSITE_URL/**'],
actions: [
{
indexName: 'YOUR_INDEX_NAME',
pathsToMatch: ['https://YOUR_WEBSITE_URL/**'],
recordExtractor: ({ $, helpers }) => {
// priority order: deepest active sub list header -> navbar active item -> 'Documentation'
const lvl0 =
$(
'.menu__link.menu__link--sublist.menu__link--active, .navbar__item.navbar__link--active'
)
.last()
.text() || 'Documentation';

return helpers.docsearch({
recordProps: {
lvl0: {
selectors: '',
defaultValue: lvl0,
},
lvl1: ['header h1', 'article h1'],
lvl2: 'article h2',
lvl3: 'article h3',
lvl4: 'article h4',
lvl5: 'article h5, article td:first-child',
lvl6: 'article h6',
content: 'article p, article li, article td:last-child',
},
indexHeadings: true,
aggregateContent: true,
recordVersion: 'v3',
});
},
},
],
initialIndexSettings: {
YOUR_INDEX_NAME: {
attributesForFaceting: [
'type',
'lang',
'language',
'version',
'docusaurus_tag',
],
attributesToRetrieve: [
'hierarchy',
'content',
'anchor',
'url',
'url_without_anchor',
'type',
],
attributesToHighlight: ['hierarchy', 'content'],
attributesToSnippet: ['content:10'],
camelCaseAttributes: ['hierarchy', 'content'],
searchableAttributes: [
'unordered(hierarchy.lvl0)',
'unordered(hierarchy.lvl1)',
'unordered(hierarchy.lvl2)',
'unordered(hierarchy.lvl3)',
'unordered(hierarchy.lvl4)',
'unordered(hierarchy.lvl5)',
'unordered(hierarchy.lvl6)',
'content',
],
distinct: true,
attributeForDistinct: 'url',
customRanking: [
'desc(weight.pageRank)',
'desc(weight.level)',
'asc(weight.position)',
],
ranking: [
'words',
'filters',
'typo',
'attribute',
'proximity',
'exact',
'custom',
],
highlightPreTag: '<span class="algolia-docsearch-suggestion--highlight">',
highlightPostTag: '</span>',
minWordSizefor1Typo: 3,
minWordSizefor2Typos: 7,
allowTyposOnNumericTokens: false,
minProximity: 1,
ignorePlurals: true,
advancedSyntax: true,
attributeCriteriaComputedByMinProximity: true,
removeWordsIfNoResults: 'allOptional',
separatorsToIndex: '_',
},
},
});