最近我用 Fuse 和 Hugo 导出的全站结构化数据(压缩后仅 2MB)做的即时搜索,还有快捷搜索地址 https://jimmysong.io/search/?q=关键词,定制了下结果展示页面,这就是开源的强大之处,任何地方都可以私人订制。
下面我将分享下如何为你的 Hugo 网站添加即时搜索功能。大体步骤如下:
读者可以参考 hugo-blox-builder 这个项目中的搜索实现,下面是参考的代码:
首先,你需要为你的 Hugo 网站创建一个 JSON 文件,它将包含所有页面的必要元数据,如标题、描述、链接等。你可以通过 Hugo 的自定义输出格式来实现这一点。
在你的 Hugo 配置文件(通常是 config.toml
或 config.yaml
)中,添加一个自定义输出格式:
[outputs]
home = ["HTML", "RSS", "JSON"]
[outputFormats.JSON]
mediaType = "application/json"
baseName = "index"
isPlainText = false
然后,在你的内容模板中(如 layouts/_default/list.json.json
),定义输出的 JSON 结构:
{
"data": [
{{ range .Pages }}
{
"title": "{{ .Title }}",
"url": "{{ .Permalink }}",
"summary": "{{ .Summary }}"
}
{{ if not (eq .Next nil) }},{{ end }}
{{ end }}
]
}
这将为你的整个站点生成一个 index.json
文件,其中包含所有页面的基本信息。当然你可能不想导出网站的所有页面,可以通过 Hugo 的语法,可定制化导出的 Section 或者不同类型页面。
接下来,使用 Fuse.js 库来实现前端的即时搜索功能。首先,你需要在你的网站中包含 Fuse.js 的库文件。你可以从 jsDelivr 等 CDN 加载它:
<script src="https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.min.js"></script>
然后,在你的 JavaScript 文件中,加载并解析 index.json
文件,并使用 Fuse.js 进行搜索:
fetch('/index.json')
.then(response => response.json())
.then(data => {
const fuse = new Fuse(data.data, {
keys: ['title', 'summary'],
includeScore: true
});
document.getElementById('search-input').addEventListener('input', function (e) {
const results = fuse.search(e.target.value);
displayResults(results);
});
});
function displayResults(results) {
const searchResults = document.getElementById('search-results');
searchResults.innerHTML = '';
results.forEach(result => {
const elem = document.createElement('div');
elem.innerHTML = `<a href="${result.item.url}">${result.item.title}</a>`;
searchResults.appendChild(elem);
});
}
具体实现可以参考 wowchemy-search.js。
在你的网站中添加一个搜索框和结果显示区域:
<input type="text" id="search-input" placeholder="输入搜索词">
<div id="search-results"></div>
另外你还可以添加搜索快捷键,一般是组合键 ⌘/CTRL + K
来快速打开搜索页面。
具体实现可以参考 这个前端模板。
为了保证搜索结果的实时性,可以通过 GitHub Actions 或其他 CI/CD 工具来自动化 Hugo 网站的构建和部署流程,确保 index.json
文件始终是最新的。
创建一个 .github/workflows/hugo_build.yml
文件,定义自动化流程:
name: Build and Deploy
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
另外如果你的网站支持多语言,可以为每种语言分别生成 index.json
文件,并在不同的语言页面加载对应的索引文件。
index.json
设置合理的缓存策略,以减少服务器负载和提高响应速度。如果你是会用的是 Github Pages 作为静态网站,那么可以忽略这一步。index.json
文件,你可以选择导出网站的部分数据,比如某些 Section 的数据,对 Content 进行截取,或者压缩文件成 gz 格式,在 JavaScript 加载后再在前端解压,这样可以减少网络数据传输。通过这些步骤,你可以有效地为你的 Hugo 网站添加一个高效且可定制的即时搜索功能。
本文介绍了如何为 Hugo 网站添加即时搜索功能,并提供了进一步优化搜索功能的建议,包括缓存优化、搜索结果高亮显示和高级搜索选项。这不仅展示了开源技术的强大自定义能力,也使网站用户能更快更准确地找到所需信息。
最后更新于 2024/12/11