Introduction
Recently, I was looking into converting my blog to use hugo modules and saw that hugo supports splitting the configuration file into multiple components. I really liked this idea and decided to give it a try.
Splitting the configuration
allows setting different options for development and production. This is really
handy because while writing new posts I use hugo server and I have to use a
variety of flags -D -F in order to include drafts and future posts. This is
because these are off by default.
With a split config I can have development turn these on so I don’t have to specify flags. On top of that, I can have different options between development and production for things that aren’t command line flags.
Layout
I decided to split into three configuration environment.
_default: Base configurationdevelopment: Develop specific settingsproduction: Production specific settings
Settings are inherited from _default and are overridden
by the environment specific configuration.
Custom environments can be specified based on the directory
name. Running hugo with the -e option allows specifying the
configuration environment.
I further split the hugo.yaml into individual files for
each root configuration key I’m using. This makes it easier
to find settings and see differences between each environment.
The hugo documentation lists root configuration keys that can be split into their own file. Custom sections used by modules or themes that not standard shouldn’t be put into a separate file per the docs. However, I’m not sure if this is actually true but it’s better to err on the side of the docs.
❯ ls -R config
_default/ development/ production/
config/_default/:
hugo.yaml menus.yaml params.yaml permalinks.yaml
config/development/:
hugo.yaml
config/production/:
minify.yaml module.yaml
Files
One interesting thing about using split files for root configuration keys is, you omit the key itself from the top level. This leaves the file a bit cleaner and easier to work with.
I’m not going to go through every setting but I’m going to post the full contents to make it easier to understand how each file operates.
_default/
Most of the configuration falls in to this directory because it applies across both development and production.
hugo.yaml
The hugo.yaml can include any settings including sections that could
be in other files. For example, instead of having menus.yaml you
can put the menus section within this file.
That said, any settings that are top level or don’t fall under a root configuration key, that can be put into it’s own file, are put in this file.
baseURL: https://nachtimwald.com/
title: John's Blog
description: My little blog
languageCode: en-us
timeZone: America/New_York
enableRobotsTXT: true
timeout: 120
theme:
- github.com/adityatelange/hugo-PaperMod
I only have root level parameters and opted to move everything else into their own file.
main:
- identifier: Archive
name: Archive
url: /archive/
weight: 10
- identifier: Tags
name: Tags
url: /tags/
weight: 20
- identifier: Legal
name: Legal
url: /legal/
weight: 30
- identifier: Search
name: Search
url: /search/
weight: 40
params.yaml
description: My little blog
homeInfoParams:
Title: Hi there
Content: |
Welcome to my blog and take a look around. Maybe you'll find something you'll like.
I like to write about a variety of topics but most posts are computer focused.
While I mainly write for myself, I hope that some of what I post will be useful
for others.
defaultTheme: auto
socialIcons:
- name: github
url: "https://github.com/user-none/"
- name: linkedin
url: "https://linkedin.com/in/john-schember/"
- name: email
url: "mailto:john@nachtimwald.com"
disableSpecial1stPost: true
ShowToc: true
ShowCodeCopyButtons: true
comments: false
hidemeta: false
hideSummary: false
comments: false
permalinks.yaml
page:
posts: /:year/:month/:day/:slug/
development/
hugo.yaml
buildDrafts: True
buildFuture: True
When building for development I have drafts and future posts always enabled.
This way I can run hugo server without any having to specify any flags.
production/
minify.yaml
minifyOutput: true
module.yaml
imports:
- path: github.com/lkhrs/hugo-dark-visitors
I’m only including the Dark Visitors plugin when building in production to
ensure it isn’t run unintentionally. The robots.txt template
file I created detects production vs development builds and omits using the
plugin.
Setting Config Environment
By default running hugo server will use the development environment. Calling hugo
alone, which builds the site, will use the production environment.
Don’t forget, you can use the -e flag to specify a specific environment.
Conclusion
All of this work just so I don’t have to specify two flags when running hugo server;
it was worth it. Not because of the flags but because it’s clear what functionality
is used in development versus production. Also, it’s very easy to understand the configuration
because it’s not one file that keeps growing in size. For example, I can easily tweak menus by going
to the menu file instead of having the settings in the middle of a larger file.
While I don’t make configuration changes often, this will make it a bit easier to administer and maintain over the long term.

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.