我的旧博客基于 Hugo 0.111.3 + hugo-coder 主题运行了三年多,最近升级到 Hugo 0.164.0 并换用了 PaperMod 主题。整个过程比预想的顺利,但还是踩了几个坑,记录一下供有类似需求的朋友参考。
迁移背景
| 旧博客 | 新博客 | |
|---|---|---|
| Hugo 版本 | 0.111.3 | 0.164.0 |
| 主题 | hugo-coder | PaperMod |
| 配置文件 | config.toml | hugo.yaml |
| 域名 | blog.wangyu.link | wangyu.link |
两个版本隔了约 50 个 minor 版本,配置格式从 TOML 切换到 YAML,主题也完全不同。迁移的核心工作就是三个:内容搬迁、配置映射、兼容性处理。
内容搬迁
这一步最简单——直接把 content/ 目录下的所有 markdown 文件复制过去就行。
cp -r personal-blog/content/* NormanBlog/content/
我的旧博客有 90+ 篇文章和 3 个独立页面(About、Projects、List),frontmatter 都是标准的 Hugo 格式,不需要任何修改就能被新版本识别。
静态资源同理:
cp -r personal-blog/static/* NormanBlog/static/
favicon、avatar、site.webmanifest 等直接搬过去即可。
配置映射:从 hugo-coder 到 PaperMod
这才是迁移的重头戏。两个主题的参数体系完全不同,需要逐一对照映射。
基本配置
# hugo.yaml (PaperMod)
baseURL: https://wangyu.link/
locale: en # Hugo 0.158+ 废弃了 languageCode
title: Norman's Blog
theme: ["PaperMod"]
paginate: 20
旧配置中的 languagecode = "en" 在 Hugo 0.158.0 之后被废弃了,需要改成 locale: en。如果继续用 languageCode,构建不会失败,但会一直弹出 deprecation 警告。
个人信息与首页
hugo-coder 用简单的 key-value 展示个人信息:
[params]
author = "Norman Wang"
info = "Front-end / Electronjs Development Engineer"
avatarurl = "images/avatar.png"
PaperMod 有两种首页模式:profileMode 和 homeInfoParams。我选择了更简洁的 homeInfoParams:
params:
author: Norman Wang
homeInfoParams:
Title: "Norman Wang"
Content: "Front-end / Electronjs Development Engineer"
label:
text: "Norman's Blog"
icon: /images/avatar.png
iconHeight: 35
社交链接
这是最容易踩坑的地方。hugo-coder 使用 Font Awesome 图标类名:
[[params.social]]
name = "Github"
icon = "fa fa-github fa-2x"
url = "https://github.com/blogwy"
PaperMod 则内置了自己的 SVG 图标集,通过 name 字段匹配:
params:
socialIcons:
- name: github
url: "https://github.com/blogwy"
- name: email
url: "mailto:wangyu@wangyu.link"
- name: rss
url: "https://..."
PaperMod 支持的图标名称包括 github、email、rss、x(Twitter)、stackoverflow、linkedin 等几十种——不需要引入任何外部图标库。
代码高亮
旧配置:
[markup.highlight]
style = "github-dark"
PaperMod 的 sample config 提示需要额外设置 pygmentsUseClasses: true,但在我的实际测试中,直接保留 highlight 配置就能正常工作:
markup:
highlight:
style: github-dark
菜单 & 分类
这部分两个主题的配置方式很接近,几乎可以直接平移:
menu:
main:
- identifier: blog
name: Blog
url: /posts/
weight: 1
- identifier: projects
name: Projects
url: /projects/
weight: 2
# ...
taxonomies:
category: categories
series: series
tag: tags
author: authors
兼容性问题的坑
1. Goldmark 不再默认允许原始 HTML
Hugo 0.111.3 中,Goldmark 渲染器默认允许 Markdown 中嵌入原始 HTML。0.164.0 出于安全考虑默认关闭了。我的几篇旧文章里嵌了 <iframe> 和 <style> 标签,构建时会报:
WARN Raw HTML omitted while rendering "..."
而且 HTML 标签被直接删掉,页面内容不完整。解决方案是在配置中显式开启:
markup:
goldmark:
renderer:
unsafe: true
2. 主题模板的废弃 API 调用
PaperMod 的部分模板使用了 .Language.LanguageCode 和 .Language.LanguageDirection,这两个 API 在 Hugo 0.158.0 被标记为废弃。每次构建都会弹出警告,但不影响功能。
这个问题需要等 PaperMod 主题更新模板才能彻底解决。如果你在意干净的构建输出,可以自行修改主题模板,将 .Language.LanguageCode 替换为 .Language.Locale,.Language.LanguageDirection 替换为 .Language.Direction。
3. 主题子模块的版本
旧博客的 .gitmodules 里还残留了 ananke 和 hugo-coder 两个子模块。迁移后只需要保留 PaperMod:
[submodule "themes/PaperMod"]
path = themes/PaperMod
url = https://github.com/adityatelange/hugo-PaperMod.git
主题特性对比
PaperMod 相比 hugo-coder 多了一些开箱即用的能力:
- 暗色/亮色模式自动切换(跟随系统 + 手动切换按钮)
- 搜索(基于 Fuse.js 的客户端搜索,零依赖)
- 代码复制按钮
- 社交分享按钮
- 面包屑导航
- 阅读时间 & 字数统计
- 文章封面图
这些功能在 hugo-coder 上要么不支持,要么需要手动配置。
迁移检查清单
如果你也需要做类似的迁移,可以按以下顺序操作:
- 备份旧博客 —— 整个目录打个 zip,随时可以回滚
- 复制内容 ——
content/和static/直接搬 - 配置映射 —— 对照新旧主题文档逐项迁移
- 构建验证 ——
hugo命令跑一遍,看有没有报错 - 本地预览 ——
hugo server -D检查页面效果 - 修复警告 —— 处理 deprecation 和兼容性问题
- 部署上线 —— 确认无误后推送
总结
整个迁移从探索结构到构建成功花了不到半小时。Hugo 的向后兼容性做得相当不错,三年前的 markdown 内容完全不需要修改。主要的精力花在适配新主题的配置参数上——这部分如果直接参考主题的 exampleSite 配置模板,可以省很多时间。
如果你也在考虑从老版本 Hugo 迁移,放心动手吧,比想象中简单得多。