5分钟搞定!给Next.js项目集成Algolia DocSearch搜索功能
前言
半年前,我开源了一个 Next.js 博客模板。当时为了实现站内搜索,我选择了 FlexSearch 方案。FlexSearch 是一个高性能的全文搜索库,在英文环境下表现优异。然而在实际测试中,我发现中文搜索存在严重问题。要解决这个问题,就需要引入 nodejieba
这样的中文分词库。但 nodejieba
依赖 C++ 编译环境,而我的网站都是部署在 serverless 环境,无法直接支持,所以那时候我只在模板里放了一个简化版的搜索,使用体验并不好。
因为搜索功能使用频率太低了,所以我后来就没怎么研究了。直到和阿伟一起开发 Next.js 中文文档 的时候,阿伟给文档站集成了 Algolia DocSearch,我才重新准备修改博客模板的搜索功能。让我惊讶的是,集成 DocSearch 太方便了,我花了5分钟就上线新的搜索功能。
Algolia DocSearch 简介
Algolia 提供了付费的企业版和免费的 DocSearch 两种方案。DocSearch 专门针对技术文档、博客等内容网站,只要你的网站是公开可访问的,就能免费集成。
DocSearch 凭借专业的搜索能力和丝滑的用户体验,已经成为技术文档的主流搜索方案。连 React 和 Vue 这样的官方网站都在使用。
这篇教程将手把手带你在 Next.js 项目中集成 DocSearch,只需跟随以下步骤,你也能很快为网站添加专业级的站内搜索。
1、申请 DocSearch
-
等待 Algolia 团队的邮件,等待了一天,我就收到了这样的一封邮件:
收到邮件就表示 Algolia 已经索引好了我们的网站,现在就可以集成了。注意圈起来的参数,后面开发的搜索框组件需要使用这三个核心参数。
2、代码集成
安装依赖
# 使用 npm
npm install @docsearch/css @docsearch/react
# 使用 yarn
yarn add @docsearch/css @docsearch/react
# 使用 pnpm
pnpm add @docsearch/css @docsearch/react
创建配置文件 config/docSearchConfig.ts
:
interface DocSearchConfig {
docSearch: {
appId: string;
indexName: string;
apiKey: string;
}
}
export const docSearchConfig: DocSearchSiteConfig = {
docSearch: {
appId: "填写邮件收到的参数",
indexName: "填写邮件收到的参数",
apiKey: "填写邮件收到的参数",
},
}
创建 DocSearch 搜索框组件 components/DocSearch/index.ts
,实现一个功能完备的搜索组件:
"use client";
import { docSearchConfig } from "@/config/docSearch";
import "@docsearch/css";
import { DocSearchModal, useDocSearchKeyboardEvents } from "@docsearch/react";
import Link from "next/link";
import { useCallback, useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { IoIosSearch } from "react-icons/io";
import "./docSearch.css";
export default function CustomDocSearch() {
const { appId, indexName, apiKey } = docSearchConfig.docSearch;
const [isOpen, setIsOpen] = useState(false);
const [isMac, setIsMac] = useState(false);
const searchButtonRef = useRef<HTMLButtonElement>(null);
const onOpen = useCallback(() => {
setIsOpen(true);
}, [setIsOpen]);
const onClose = useCallback(() => {
setIsOpen(false);
}, [setIsOpen]);
useDocSearchKeyboardEvents({
isOpen,
onOpen,
onClose,
searchButtonRef,
});
// 添加检测操作系统的效果
useEffect(() => {
setIsMac(navigator.platform.toUpperCase().indexOf("MAC") >= 0);
}, []);
return (
<>
<button className="docSearch-btn" data-variant="large" onClick={onOpen}>
搜索文档<kbd>{isMac ? "⌘K" : "Ctrl+K"}</kbd>
</button>
<button className="docSearch-btn" data-variant="medium" onClick={onOpen}>
搜索<kbd>{isMac ? "⌘K" : "Ctrl+K"}</kbd>
</button>
<button
className="docSearch-btn mr-2 hover:bg-accent border border-gray-300"
data-variant="small"
onClick={onOpen}
>
<IoIosSearch />
</button>
{isOpen &&
createPortal(
<DocSearchModal
initialScrollY={window.scrollY}
appId={appId}
apiKey={apiKey}
indexName={indexName}
onClose={onClose}
placeholder="搜索文档"
hitComponent={({ hit, children }) => (
<Link href={hit.url}>{children}</Link>
)}
/>,
document.body
)}
</>
);
}
docSearch.css
是自定义的搜索样式,这部分不重要,不贴代码了,你可以到文末的开源地址查看。
再把搜索框组件 CustomDocSearch
引入 Header 就可以使用了。
总结
DocSearch 的搜索和集成都非常方便,现在我的博客模板、博客、信息差周刊都已经集成好了,这三个项目都是开源的,你可以直接复制我的组件代码。
也可以到「Next.js中文文档」体验,文档站一共有 300 多个文档,搜索效率依然非常高,所以你完全可以放心使用。
关于我
我是一名全栈工程师,Next.js 开源手艺人,AI降临派。
今年致力于 Next.js 和 Node.js 领域的开源项目开发和知识分享。
欢迎在以下平台关注我:
- Twitter(中文): @weijunext
- Github: Github
- Blog: J实验室
- 微信交流群: 全栈交流群
- 全栈教程:Chrome插件+Next.js全栈专栏