Hugo Modules: Importing a Theme
— Kaushal ModiA brief guide on how to install Hugo themes using Hugo Modules.
This is a post in the “Hugo Modules” series.
2022-05-26 | Hugo Modules: Importing a Theme |
2022-02-24 | Hugo Modules: Getting Started |
Hello! You are reading this post because you are probably interested in the Hugo Modules feature and are considering to import a Hugo Module as a theme.
Step 0 for that approach is to make your site repo a Hugo Module. If
your site already is, then it would have a go.mod
file in the repo
root. If you don’t have the go.mod
file, check out the previous post
Hugo Modules: Getting Started first ‼️
If you don’t have a go.mod
file for your site repo, and you still
decide to continue with the next steps, don’t complain if you see
errors like module “foo” not found; either add it as a Hugo Module or
store it in “<your site repo>/themes”.: module does not exist. —
speaking from experience 😉.
With that out of the way, here are the next steps ..
1 Clean up the old way of setting a theme #
If you are upgrading your Hugo site to switch from the legacy method
of using themes (i.e using the theme
variable in the site config
In my posts, you may have seen me use the Site Config term or
config.toml
– They mean the same thing.
), you need to clean that up.
- Remove the
theme
variable from your site config. - Remove the
themes
directory, or move it out of your Hugo site repo.- If you were cloning a theme developed by someone else in there, you can just remove this directory.
- If you are maintaining your own theme in that directory, move it out of your site repo and convert it to a Hugo Module.
2 Import the “theme” module #
The theme is quoted in this title, because the concept of a Hugo “theme” is a bit old now (
) and that has been superseded with the concept of “modules”.The main difference between a theme and a generic Hugo Module is that the former will allow you to build your site entirely, while the latter might implement only some modular features like enabling the ATOM feed, or adding a search to your website.
I am mentioning this again for convenience, from the previous post in this series:
A module can be your main project or a smaller module providing one or more of the 7 component types defined in Hugo: static, content, layouts, data, assets, i18n, and archetypes. You can combine modules in any combination you like, and even mount directories from non-Hugo projects, forming a big, virtual union file system.
A theme will need to have the “layout” component. Additionally, it might have the “assets”, “static”, and other components too.
Importing a module as a theme will typically look like this in your site config:
[module]
[[module.imports]]
path = "URL of the theme's git remote *without* the 'https://' part"
The path here would be something like
github.com/USER/THEME-REPO-NAME
or
gitlab.com/USER/THEME-REPO-NAME
.
- Note
- It’s possible to take any Hugo theme git repo and import
that as a Hugo Module even if that repo isn’t actually one
i.e. doesn’t have a
go.mod
. But it’s recommended that the theme be a proper Hugo Module so that you have better dependency tracking between your site and the theme.
Quick Example #
Follow these steps if you want to try out how this Hugo Module based theme importing
As a reminder, you need to have Go installed on your system.
- Create a temporary directory somewhere and
cd
to it. - Initialize your site as a Hugo Module:
hugo mod init foo
(yeah, type that out literally — it will work) - Create a
config.toml
file with the below content. It imports thehugo-mwe-theme
hugo-mwe-theme
is a minimal Hugo theme that I use to quickly try out some new feature in Hugo or to create a minimal working example to reproduce a bug. theme.[module] [[module.imports]] path = "gitlab.com/kaushalmodi/hugo-mwe-theme"
- Create
content/hello.md
. This step is optional and is only so that your test site as some content.+++ title = "Hello" +++ Hey!
That’s it! Now run the Hugo server (hugo server
) and look at your
site running on localhost .. while thinking in disbelief.. just how
easy all of this was! 😃.
- Did you need to manually clone any theme? No
- Would you need to deal with the
.gitmodules
file? No
3 hugo mod tidy
#
Finally, run hugo mod tidy
to clean up the go.mod
and
update/generate the go.sum
file. These files will track the module
dependencies for your site.
- The
go.mod
contains the direct module dependencies for your site. - The
go.sum
contains the versions and hashes of all the direct and indirect dependencies Just as you added a theme as a Hugo Module to your site, it’s possible that that theme is depending on other Hugo Modules (like the ones I mentioned earlier: ATOM feeds, search, etc.). for your site.
You would need to commit the go.mod
and go.sum
1 files if you
build and deploy your website on a remote server or a CI/CD system.
If you ran the Quick Example, you will see this (as of
) in your go.mod
:
module foo
go 1.18
require gitlab.com/kaushalmodi/hugo-mwe-theme v0.1.1 // indirect
.. and this in your go.sum
:
gitlab.com/kaushalmodi/hugo-mwe-theme v0.1.1 h1:FyTp43CJRpBfoHyWnwQFx//cipgP6xQ9/uucj+qjj1U=
gitlab.com/kaushalmodi/hugo-mwe-theme v0.1.1/go.mod h1:vvq0r/SfKMbiPbyqL4YottSOkpCkBSosqGRm82aDNrU=
4 Updating the theme #
Here are some common ways to update the theme module going forward:
Command | Description |
---|---|
hugo mod get -u | Update only the modules that your site directly depends on. |
hugo mod get -u ./... | Update the modules that your site depends on in a recursive fashion. |
Additionally, you might or might not need these, but I am documenting them here for completeness:
Command | Description |
---|---|
hugo mod get -u <module path> | Update only the specified module2 to the latest version. Example: hugo mod get -u gitlab.com/kaushalmodi/hugo-mwe-theme |
hugo mod get <module path>@<git ref> | Update a module to the specified git tag or commit. Example: hugo mod get gitlab.com/kaushalmodi/hugo-mwe-theme@v0.1.1 |
Dependency Graph #
If you have a theme added as a Hugo Module, which depends on other Hugo Modules, it’s often helpful to know the dependency graph. You can do that by running:
hugo mod graph
For the above Quick Example, you will see just this one line because that theme does not depend on other modules:
foo gitlab.com/kaushalmodi/hugo-mwe-theme@v0.1.1
Building your Hugo site on a server #
Alright, so you are able to build your site locally after switching to using themes as modules, great!
Now, if you build and deploy your site on a remote server like Netlify or Vercel, you need to ensure that you have a recent version of Go installed in their environment too.
I deploy this website using Netlify, and so I know how to do that
there — Set the GO_VERSION
environment variable to a recent
version like 1.18 in the Environment variables section in Netlify
Build & deploy settings.
In a nutshell #
- First convert your Hugo site to a Hugo module.
- Then replace the
theme
in your site config with a module import.
Enjoy! 🍾
References #
It is recommended to git commit the
go.sum
along with your site’sgo.mod
. From the Go Modules documention: Ensure yourgo.sum
file is committed along with yourgo.mod
file. See FAQ below for more details and rationale. ↩︎Trust me.. once you get a hang of the Hugo Module system, your site will have more than one! ↩︎