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
themevariable from your site config. - Remove the
themesdirectory, 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
cdto it. - Initialize your site as a Hugo Module:
hugo mod init foo(yeah, type that out literally — it will work) - Create a
config.tomlfile with the below content. It imports thehugo-mwe-themehugo-mwe-themeis 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"Code Snippet 1: Example of importing a Hugo module as a theme inconfig.toml - 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
.gitmodulesfile? 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.modcontains the direct module dependencies for your site. - The
go.sumcontains 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.sum1 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
themein your site config with a module import.
Enjoy! 🍾
References #
It is recommended to git commit the
go.sumalong with your site’sgo.mod. From the Go Modules documention: Ensure yourgo.sumfile is committed along with yourgo.modfile. 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! ↩︎