跳到主要内容

为 Docusaurus 添加 Algolia 搜索功能

· 阅读需 14 分钟
Eureka X
Mr.Nobody

本文介绍使用 Algolia 为 Docusaurus 网站添加搜索功能。

配置 Algolia 教程 🔎​

我参考了这篇文章为我的网站添加了搜索功能。但是在实践过程中遇到了一些问题,原文章说明也不够详细,因此决定写一篇更加详细的博客来记录整个配置过程。

获取 Algolia API​

本小节的目标是获取 Algolia 的这三个 API:

1. Application ID
2. Search API Key
3. Admin API Key

API 名称对应关系​

Algolia中 的 API 名称和代码中的名称并不完全一致,对应关系如下:

docusaurus.config.js
Application ID -> appId
Search API Key -> apiKey
Actions secrets
Application ID -> ALGOLIA_APP_ID
Admin API Key -> ALGOLIA_API_KEY

注册 Algolia 账户​

  1. 打开 Algolia官网 ,使用Github账号注册并登录

  1. 点击 Not now ... 跳过初始设置

获取 API​

  1. 打开 Settings 配置页面

  1. 查看API Key

上面三个 API 即为所需,此页面可保持打开,方便后续复制粘贴。 至此,三个 API 应已成功获取。

重要提醒

不要分享 Admin API Key! 这是敏感信息,泄露可能导致安全问题。!

只找到两个 API ?

如果在查看 API 的时候看到只有两个 API,分别是 Application ID 和 Search API Key,没有 Admin API Key ?!那说明刚才没有严格按照这个步骤走,现在看到的是Algolia 默认创建的 Application Docsearch 。该 Application 暂时是没有 Admin API Key 密钥的。(按官方的教程一步步走应该会有,但我没试过。🥱)解决方法是再创建一个 Application,在这里:Settings/API Keys

填上名称后,其他配置保持默认,直接点击 Next:Review & Confirm -> Create Application。新Application 的 API 获取方式与上面一样。

创建 Actions Secrets​

  1. 打开存放网站项目代码的 Github 仓库,进入:Settings/Secrets and variables/Actions。

  1. 返回 Algolia 页面,复制 Application ID:

  1. 返回 Github 页面,填上名称 ALGOLIA_APP_ID,粘贴秘钥,点击 Add secret。

  1. 返回 Algolia 页面,复制 Admin API Key:

  1. 返回 Github 页面,填上名称 ALGOLIA_API_KEY,粘贴秘钥,点击 Add secret。

  1. 预期结果:

创建 Github Actions workflow​

  • 可以在本地项目根目录下创建 .github/workflows/docsearch.yml 文件:

以下将提供两个 docsearch.yml 配置,分别为原始版本和改进版本。

这是两个版本的对比:

原始版本:从参考资料的文章中复制修改,功能基础。

改进版本:解决实际问题而生——网站有100+记录但只爬取到16条且显示成功。

改进版本新增功能:

  • 输出详细错误信息
  • 爬取记录过少时工作流失败并提示

配置要点:根据网站实际记录数调整高亮行配置,如网站约100条则配置为100,后续可随内容变化调整。如不知道自己的网站记录具体有多少条,可以先值改低一点,比如改为1,这样即使只爬取到一条记录,也会显示执行成功,这时候已经得到具体的记录数了,再修改为具体记录数相近的数值。

.github/workflows/docsearch.yml
name: DocSearch Scraper

on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *'

jobs:
algolia:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install jq
run: sudo apt-get install jq

- name: Validate docsearch.json exists
run: |
if [ ! -f "docsearch.json" ]; then
echo "docsearch.json not found!"
exit 1
fi

- name: Get the content of docsearch.json as config
id: algolia_config
run: echo "config=$(cat docsearch.json | jq -r tostring)" >> $GITHUB_OUTPUT

- name: Run algolia/docsearch-scraper image
env:
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}
CONFIG: ${{ steps.algolia_config.outputs.config }}
run: |
echo "Starting DocSearch scraper..."
# 捕获输出并检查退出码
docker run \
--env APPLICATION_ID=${ALGOLIA_APP_ID} \
--env API_KEY=${ALGOLIA_API_KEY} \
--env "CONFIG=${CONFIG}" \
algolia/docsearch-scraper > scraper_output.log 2>&1
echo "DocSearch scraper execution finished."

- name: Validate scraping results
run: |
# 显示完整的抓取日志(便于调试)
echo "=== SCRAPER OUTPUT ==="
cat scraper_output.log
echo "=== END OUTPUT ==="

# 检查是否有错误信息
if grep -q "ERROR\|Exception\|Traceback" scraper_output.log; then
echo "ERROR: Scraper encountered errors during execution"
exit 1
fi

# 提取抓取的记录数
hits=$(grep "Nb hits:" scraper_output.log | awk '{print $3}')
if [ -z "$hits" ]; then
echo "ERROR: Could not determine number of hits"
exit 1
fi

echo "Records scraped: $hits"

# 验证记录数量是否合理
if [ "$hits" -lt 100 ]; then
echo "ERROR: Insufficient records scraped ($hits < 100). This indicates incomplete scraping."
exit 1
fi
echo "SUCCESS: Adequate records scraped ($hits >= 100)"

- name: Archive scraper logs
uses: actions/upload-artifact@v4
if: always()
with:
name: scraper-logs-${{ github.run_id }}-${{ github.run_attempt }}
path: scraper_output.log
两个版本的详细比对

功能完整性对比​

1. 错误检测和验证机制

原始版本(较差):

run: |
echo "Starting DocSearch scraper..."
docker run \
--env APPLICATION_ID=${ALGOLIA_APP_ID} \
--env API_KEY=${ALGOLIA_API_KEY} \
--env "CONFIG=${CONFIG}" \
algolia/docsearch-scraper
echo "DocSearch scraper completed successfully." # 总是显示成功

改进版本(较好):

- name: Validate scraping results
run: |
# 完整的验证机制
# 1. 显示完整日志
cat scraper_output.log

# 2. 错误检测
if grep -q "ERROR|Exception|Traceback" scraper_output.log; then
echo "ERROR: Scraper encountered errors"
exit 1
fi

# 3. 结果数量验证
if [ "$hits" -lt 100 ]; then
echo "ERROR: Insufficient records"
exit 1
fi

2. 日志记录和调试能力

原始版本缺陷:

  • 没有捕获详细输出
  • 遇到问题时难以诊断
  • 无法查看实际执行过程

改进版本优势:

# 捕获完整输出用于分析
docker run ... > scraper_output.log 2>&1

# 显示完整日志便于调试
echo "=== SCRAPER OUTPUT ==="
cat scraper_output.log

具体改进点分析​

1. 真实成功验证

原始版本问题:
❌ 只要程序运行完成就显示成功
❌ 无法区分"运行完成"和"成功完成"
❌ 16条记录也会显示成功

改进版本优势:
✅ 检查实际抓取的记录数量
✅ 验证是否达到预期标准
✅ 只有真正成功才标记为成功

2. 错误处理机制

原始版本问题:
❌ 没有错误检测
❌ 静默失败无法发现
❌ 网络问题或配置错误无法识别

改进版本优势:
✅ 自动检测错误信息
✅ 关键词匹配发现异常
✅ 及时终止并报告错误

3. 调试和监控能力

原始版本限制:
❌ 无日志记录
❌ 无法回溯问题
❌ 难以优化性能

改进版本功能:
✅ 完整日志捕获
✅ 日志归档保存
✅ 便于问题分析和性能优化

实际场景对比​

场景1:网络连接问题

原始版本结果:
- 只抓取了16条记录
- 工作流显示"成功"
- 你不知道有问题

改进版本结果:
- 只抓取了16条记录
- hits < 100,工作流失败
- 通过日志可以发现问题原因

场景2:配置文件错误

原始版本结果:
- 程序异常退出但仍可能显示成功
- 无法定位配置问题

改进版本结果:
- 捕获错误日志
- grep 检测到 "ERROR" 关键词
- 工作流正确失败并提示错误

场景3:正常运行

原始版本:
- 显示成功但信息有限

改进版本:
- 显示详细的执行过程
- 验证记录数量充足
- 保存完整日志供后续分析

可靠性和维护性​

1. 监控能力

原始版本:
- 盲目信任执行结果
- 无法主动发现问题

改进版本:
- 主动验证执行质量
- 设置合理的阈值标准
- 及早发现潜在问题

2. 故障排查

原始版本:
- 出问题时需要手动检查
- 缺乏诊断信息

改进版本:
- 自动化的错误检测
- 完整的日志记录
- 快速定位问题根源

3. 持续改进

原始版本:
- 难以收集运行数据
- 无法优化性能

改进版本:
- 积累历史执行日志
- 分析性能趋势
- 持续优化工作流

总结​

改进后的版本在以下方面明显优于原始版本:

  1. 准确性:从表面成功到真实成功验证
  2. 可靠性:完善的错误检测和处理机制
  3. 可维护性:详细的日志记录和分析能力
  4. 监控性:主动的健康检查和预警机制
  5. 透明度:完整的执行过程可视化

如果想配置成部署完成后便触发该工作流,可以参考这篇文章。但我觉得手动和定时触发已经完全足够,因此没有尝试其他触发方式。

创建 docsearch.json​

下面黄色高亮部分需要改成自己的配置,index_name可自定义,但要和后续的docusaurus.config.js配置一致,start_urls和sitemap_urls改成自己的链接。

docsearch.json
{
"index_name": "test-site",
"start_urls": ["https://eureka12138github.github.io/"],
"sitemap_urls": ["https://eureka12138github.github.io/sitemap.xml"],
"js_render": true,
"js_wait": 1,
"selectors": {
"lvl0": {
"selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
"type": "xpath",
"global": true,
"default_value": "Documentation"
},
"lvl1": "header h1, article h1",
"lvl2": "article h2",
"lvl3": "article h3",
"lvl4": "article h4",
"lvl5": "article h5, article td:first-child",
"lvl6": "article h6",
"text": "article p, article li, article td:last-child"
},
"custom_settings": {
"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": "_",
"synonyms": [
["js", "javascript"],
["ts", "typescript"]
]
}
}

注意:绿色标注的两行配置(js_render 和 js_wait)非常重要。没有这两句的话,Algolia可能只能爬取到网站首页的数据。在除首页外的页面点击F12,可能会发现404页面,但此时网页是可以正常显示的。这种显示和源码不一致的情况导致无法爬取到完整数据。加上这两句表示渲染完成后再爬取,如此便能正常获取所有数据。

如果后续增加 i18n 国际化配置,想要爬取多语言数据,则需要修改docsearch.json中的 sitemap_urls。以英文站为例:

"sitemap_urls": [
"https://eureka12138github.github.io/sitemap.xml",
"https://eureka12138github.github.io/en/sitemap.xml"
],

配置 docusaurus.config.js​

  1. 位置示意:

  1. 新增代码:
docusaurus.config.js
//添加Algolia搜索
algolia: {
// Application ID
appId: '********',
// Search API Key
apiKey: '*******************',
indexName: 'test-site',//与docsearch.json中的index_name一致
searchPagePath: 'search',
contextualSearch: true
},

不记得名称对应关系?

网站部署​

将代码 git push 到远端仓库中。

手动触发工作流爬取信息​

在GitHub对应仓库中,点击 Actions,选择Docsearch scraper,点击Run workflow,即可触发该工作流,爬取网站信息并生成索引文件用于后续Algolia搜索。

运行完毕:

查看 Algolia 记录​

  1. 点击 Data Source

  1. 点击 indices,从下图可知索引文件已经生成,在索引 test-site 下一共找到了 134个记录。这个记录数量取决于网站内容,如果内容多,记录也多。我这个只是演示网站,只有134记录,正常的索引记录可能会有几千甚至上万个。

注意,只有这里出现了和你网站内容所匹配的记录时,才表示配置成功。如果网站内容很多,结果这里的记录只有寥寥几条,那明显是某个地方出错了。可能是这里的两行没有加?

将网站部署到GitPages​

其实在本地就可以查看结果了,部署再看是为了进一步确认结果是否正确。毕竟有的时候本地运行的好好的,但是部署到GitPages的时候,就出现了问题。(说的就是你!i18n,坑爹的现在闪烁问题还没能解决。。。😑)

部署完成:

结果​

大功告成!现在网站可以使用搜索功能了!🎉

这个过程还挺曲折的,多亏了下面的参考资料,没有他的文章参考,我怕是难以完成这个搜索功能。但即使有参考,也并非一蹴而就的,为了实现这个搜索功能,我花了很多时间,也走了很多弯路,希望这个总结能帮助到有缘之人。(也可能是未来的自己?🥱)

📚 参考资料​

[1]. AlanWang's Blog

加载评论中...