在配置 Hugo 时发现自己的配置文件和网上文章中的不同,于是把 config 相关的常见用法捋一遍,涵盖配置格式、拆分方式、目录约定和合并顺序等,方便以后查阅或迁移主题时少踩坑。


1. 配置该用 TOML 还是 YAML?

问题:初始化时可能用 hugo.toml(TOML),想统一成 YAML,会不会牵一发动全身?

解决:Hugo 支持根配置用 hugo.tomlhugo.yamlhugo.json(或旧版 config.*),选一种即可,没有功能差异。若从 TOML 迁到 YAML:

  • 把根配置改成 config.yamlhugo.yaml(或采用下面的 config 目录,见第 2 节)。
  • archetypes(新文章模板)里的 front matter 也可以从 +++(TOML)改成 ---(YAML),这样 hugo new 生成的文章格式与站点风格一致;已有文章不必改,Hugo 对单篇内容的 front matter 格式不挑剔。

2. 站点配置和主题配置混在一起,难维护怎么办?

问题:一个文件里既有 baseURLthememarkup 等 Hugo 核心项,又有主题的 params(如目录、字数、页脚开关),换主题或调展示时要在一大坨配置里找。

解决:用 config 目录 把配置按「职责」拆开。Hugo 会合并 config/_default/ 下所有文件(按顶层 key 深度合并),例如:

  • hugo.yaml:只放 Hugo 核心配置——baseURLlanguageCodetitletheme、分页、构建选项、outputstaxonomiesmarkup(Goldmark、代码高亮)等。
  • params.yaml:只放原本在 params 下的那些键值——主题/站点展示相关(日期格式、目录、字数、搜索参数等)。注意:在 config 目录下按「根 key」拆分时,文件内要省略根 key,即 params.yaml 里不要再写一层 params:,直接写 ShowToc: true 等即可;否则会变成 params.params.xxx,主题读 site.Params.ShowToc 会拿不到。

这样「换主题或调展示」主要动 params.yaml,「改构建/输出/高亮」主要动 hugo.yaml,职责清晰。

拆分后的目录结构(仅默认环境时):

1
2
3
4
5
blog/
└── config/
    └── _default/
        ├── hugo.yaml    # Hugo 核心配置
        └── params.yaml  # 主题/站点展示参数(params 根 key 下的内容)

hugo.yaml 简单示例(根级 key 都写在这一份里):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
baseURL: 'https://example.com/'
languageCode: zh-cn
title: '我的博客'
theme: PaperMod

pagination:
  pagerSize: 10

hasCJKLanguage: true
buildDrafts: false
enableEmoji: true

outputs:
  home: [HTML, RSS]

markup:
  tableOfContents:
    startLevel: 2
    endLevel: 3
  goldmark:
    renderer:
      unsafe: true
  highlight:
    codeFences: true
    lineNos: true
    style: darcula

params.yaml 简单示例(注意:不要写顶层 params:,直接写键值):

1
2
3
4
5
6
DateFormat: "2006-01-02"
ShowToc: true
TocOpen: true
ShowWordCount: true
ShowLastMod: true
# 主题相关项按主题文档填写,例如搜索、页脚开关等

3. 为什么会有 _default 这一层?

问题:目录是 config/_default/hugo.yaml,不能直接 config/hugo.yaml 吗?

解决:Hugo 的 config 目录是按 环境(environment) 组织的,子目录名表示环境:

  • _default:默认环境。不指定 --environment 时(如本地 hugo server、普通 hugo 构建)用的就是这里面的配置。
  • productiondevelopment 等:对应 hugo --environment production 等。Hugo 会先加载 _default,再用当前环境目录下的文件覆盖/合并同名的顶层 key。

因此 _default 不是随便起的名字,而是「默认环境」的约定目录;只有一份配置时,把文件都放在 config/_default/ 即可。


4. params.yaml 是规定好的文件名吗?

问题:必须叫 params.yaml 吗?能叫 theme-options.yaml 吗?

解决不是保留名。Hugo 合并时只看文件里的 顶层配置 key(如 paramsmarkup),与文件名无关。但官方示例和社区习惯是 文件名与顶层 key 对应,便于一眼看出每个文件管哪一块,例如:

文件名示例文件内容约定用途说明
params.yaml直接写键值,不写 params:站点/主题参数
hugo.yaml根级各项基础配置
menus.en.yamlmenus: 或按 key 省略英文菜单
languages.yamllanguages: 或省略多语言

所以用 params.yaml 是约定命名,推荐保留,便于后续维护和他人阅读。


5. 多文件、多环境如何叠加?合并顺序是什么?

问题:同环境里多个文件、以及不同环境之间,谁覆盖谁?

解决:可以分两层理解。

  • 同一环境内(如 config/_default/):该目录下所有配置文件会按 顶层 key深度合并。例如 hugo.yaml 里有 markupparams.yaml 里有 params,最终配置 = 各文件按 key 合并后的结果;同一 key 出现多次时,后加载的会覆盖先前的(与文件名字母顺序等有关,建议同一 key 只在一个文件里定义,避免混淆)。
  • 跨环境:先加载 _default,再加载当前环境(如 production)下的配置,当前环境的设置覆盖 _default。典型用法:在 config/production/params.yaml 里只写要覆盖的项(如打开统计、关闭 draft),其余继承 _default

此外,命令行可用 --config 指定若干文件,从左到右依次合并,例如:

1
hugo --config a.toml,b.yaml,c.json

适合临时覆盖或脚本化构建,与 config 目录可同时使用(命令行给出的文件会参与合并)。


6. 和主题、模块的配置谁优先?

问题:主题自带默认配置,站点也配了同名的 params,最终以谁为准?

解决:Hugo 的合并顺序是 项目配置优先于主题/模块:先加载主题的默认配置,再加载你项目里的配置(根目录单文件或 config/ 目录),项目的设置会覆盖主题默认值。在顶层 key 下还可以通过 _merge(如 deepshallownone)细调合并方式,用于需要「在主题默认值基础上追加列表」等场景。


7. 其他注意点

  • params 文件别写根 key:在 config/_default/params.yaml 里,内容直接是 ShowToc: trueDateFormat: "2006-01-02" 等,不要再包一层 params:。文件名已表示根 key,写两层会导致 site.Params.params.ShowToc,主题拿不到 site.Params.ShowToc,TOC 等依赖 params 的功能会失效。
  • cascade:若要用 cascade 做批量 front matter 继承,必须写在「根」配置里(单文件或 config 目录里某个包含根级 key 的文件),不能单独放在只含 params 键值的 params 文件中,这是 Hugo 的当前限制。
  • 换主题:采用「hugo + params 拆分」后,换主题时通常只需重点改 params.yaml(以及可能的 menus.*),核心的 hugo.yaml 大多可复用。
  • 单文件 vs 目录:小站点用根目录一个 hugo.yamlconfig.yaml 即可;配置项多了、或要区分环境时,再迁到 config/_default/ 并拆成 hugo.yaml + params.yaml 更清晰。

以上是搭建过程中用到的配置用法总结,若有新的坑或用法会再补充到本文。