最近把自己的 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.mdcontent/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

这次改造完成后,博客基本具备了一个个人站点该有的基础体验:

  • 顶部导航更简洁
  • 搜索可用
  • 站点头像统一
  • 浏览器标签页有识别度

后续可以继续优化文章目录、代码块样式、评论系统、访问统计和自动部署。