最近把自己的 Hugo 博客做了一轮基础改造,主要处理了几个小问题:
- 去掉顶部不需要的「归档」「关于」
- 增加搜索页面
- 修复搜索结果里的
undefined - 给站点名称加头像
- 把头像同步到浏览器标签页图标
下面整理一份完整记录,方便后面复用。
一、去掉顶部「归档」「关于」
Hugo 的导航菜单一般配置在 config.yaml 里。
原来可能是这样:
menu:
main:
- name: 文章
url: /posts/
weight: 10
- name: 归档
url: /archives/
weight: 20
- name: 标签
url: /tags/
weight: 30
- name: 搜索
url: /search/
weight: 40
- name: 关于
url: /about/
weight: 50
如果不想在顶部显示「归档」和「关于」,直接删掉对应菜单即可:
menu:
main:
- name: 文章
url: /posts/
weight: 10
- name: 标签
url: /tags/
weight: 30
- name: 搜索
url: /search/
weight: 40
如果不确定配置在哪里,可以搜索:
grep -R "归档\|关于\|archives\|about" -n config.yaml hugo.yaml config.toml hugo.toml themes layouts content
注意:
这里只是去掉顶部菜单,不一定要删除 content/about.md 或 content/archives.md。
二、实现搜索页面
Hugo 是静态博客,本身没有后端搜索服务。常见做法是:
Hugo 生成搜索索引 JSON,前端页面通过 JavaScript 在本地搜索。
如果使用的是 PaperMod 主题,可以直接使用主题自带的搜索能力。
1. 开启 JSON 输出
在 config.yaml 中加入:
outputs:
home:
- HTML
- RSS
- JSON
这一步会让 Hugo 生成:
/index.json
搜索页面会读取这个文件。
2. 创建搜索页面
新建文件:
vi content/search.md
内容:
---
title: "搜索"
layout: "search"
url: "/search/"
summary: "搜索文章"
---
这样 Hugo 会生成:
/public/search/index.html
3. 检查搜索页面是否生成
执行:
hugo --cleanDestinationDir
检查文件:
ls public/search/index.html
ls public/index.json
如果这两个文件都存在,说明搜索页面已经生成成功。
4. 发布到 Nginx 目录
我当前 Nginx 的站点目录是:
/usr/share/nginx/html
所以重新发布:
hugo --cleanDestinationDir
rm -rf /usr/share/nginx/html/*
cp -r public/* /usr/share/nginx/html/
访问:
https://你的域名/search/
三、修复搜索结果里的 undefined
搜索结果里出现 undefined,一般是模板里显示了某个字段,但搜索索引里没有这个字段。
例如页面里用了:
${item.date}
但是 /index.json 里没有 date 字段,就会显示:
undefined
方案一:不显示空字段
把搜索结果模板里的日期显示改成:
${item.date ? `<div style="font-size:14px;color:#888;margin-bottom:8px;">${item.date}</div>` : ""}
这样没有日期时就不会显示 undefined。
方案二:给索引补充日期字段
如果自己写了 layouts/_default/index.json,可以这样写:
[
{{- range $index, $page := where .Site.RegularPages "Type" "posts" -}}
{{- if $index -}},{{- end }}
{
"title": {{ $page.Title | jsonify }},
"url": {{ $page.RelPermalink | jsonify }},
"content": {{ $page.Plain | jsonify }},
"date": {{ $page.Date.Format "2006-01-02" | jsonify }}
}
{{- end -}}
]
然后重新生成发布。
四、给站点名称加头像
我把头像文件放在:
static/image/
Hugo 里 static 目录下的文件会原样发布到网站根路径。
例如:
static/image/avatar-round.png
发布后访问路径就是:
/image/avatar-round.png
1. 配置站点头像
在 config.yaml 里加:
params:
label:
text: "笼中橘猫"
icon: "/image/avatar-round.png"
iconHeight: 32
这样 PaperMod 左上角站点名称前面会显示头像。
2. 让头像显示为圆形
新建 CSS 文件:
mkdir -p assets/css/extended
vi assets/css/extended/custom.css
加入:
.logo a {
display: flex;
align-items: center;
gap: 8px;
}
.logo a img {
width: 32px;
height: 32px;
border-radius: 50%;
object-fit: cover;
}
如果想要文字在前、头像在后,可以这样:
.logo a img {
order: 2;
}
五、把头像应用到浏览器标签页
浏览器标签页左边的小图标叫:
favicon
准备这些文件:
static/image/favicon.ico
static/image/favicon.png
static/image/favicon-16x16.png
static/image/favicon-32x32.png
static/image/apple-touch-icon.png
然后在 config.yaml 中配置:
params:
assets:
favicon: "/image/favicon.ico"
favicon16x16: "/image/favicon-16x16.png"
favicon32x32: "/image/favicon-32x32.png"
apple_touch_icon: "/image/apple-touch-icon.png"
如果前面已经有 params,要合并写法,不要重复写多个 params。
完整示例:
params:
label:
text: "笼中橘猫"
icon: "/image/avatar-round.png"
iconHeight: 32
assets:
favicon: "/image/favicon.ico"
favicon16x16: "/image/favicon-16x16.png"
favicon32x32: "/image/favicon-32x32.png"
apple_touch_icon: "/image/apple-touch-icon.png"
发布后可以直接访问验证:
https://你的域名/image/favicon.ico
https://你的域名/image/avatar-round.png
注意:
浏览器对 favicon 缓存很强,改完后可能需要用无痕窗口打开,或者访问:
https://你的域名/?v=2
六、完整发布命令
每次改完配置、模板、CSS 或图片后,执行:
hugo --cleanDestinationDir
rm -rf /usr/share/nginx/html/*
cp -r public/* /usr/share/nginx/html/
如果改了 Nginx 配置,再执行:
nginx -t
systemctl reload nginx
七、常见问题
1. /search/ 访问 404
检查:
ls public/search/index.html
如果不存在,说明搜索页面没生成。
检查 content/search.md 是否存在:
ls content/search.md
重新生成:
hugo --cleanDestinationDir
如果 public/search/index.html 存在,但线上还是 404,说明没有正确复制到 Nginx 目录。
检查:
ls /usr/share/nginx/html/search/index.html
2. 搜索没有结果
检查:
ls public/index.json
如果没有,说明没有开启:
outputs:
home:
- HTML
- RSS
- JSON
3. 头像不显示
检查头像是否能直接访问:
https://你的域名/image/avatar-round.png
如果打不开,说明图片没有放到 static/image/,或者没有重新发布。
4. 浏览器标签图标不更新
favicon 有缓存,可以尝试:
https://你的域名/?v=2
或者使用无痕窗口打开。
也可以直接访问:
https://你的域名/image/favicon.ico
确认图标文件是否已经生效。
八、最终目录结构参考
blog-root/
├── config.yaml
├── content/
│ └── search.md
├── static/
│ └── image/
│ ├── avatar-round.png
│ ├── favicon.ico
│ ├── favicon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ └── apple-touch-icon.png
├── assets/
│ └── css/
│ └── extended/
│ └── custom.css
└── layouts/
└── partials/
└── extend_head.html
这次改造完成后,博客基本具备了一个个人站点该有的基础体验:
- 顶部导航更简洁
- 搜索可用
- 站点头像统一
- 浏览器标签页有识别度
后续可以继续优化文章目录、代码块样式、评论系统、访问统计和自动部署。