<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us"><generator uri="https://gohugo.io/" version="0.101.0">Hugo</generator><title type="html">component on A Scripter's Notes</title><subtitle type="html">Emacs, scripting and anything text oriented.</subtitle><link href="https://scripter.co/tags/component/" rel="alternate" type="text/html" title="HTML"/><link href="https://scripter.co/tags/component/index.xml" rel="alternate" type="application/rss+xml" title="RSS"/><link href="https://scripter.co/tags/component/atom.xml" rel="self" type="application/atom+xml" title="Atom"/><link href="https://scripter.co/tags/component/jf2feed.json" rel="alternate" type="application/jf2feed+json" title="jf2feed"/><updated>2026-04-22T08:24:57-04:00</updated><author><name>Kaushal Modi</name><email>kaushal.modi@gmail.com</email></author><id>https://scripter.co/tags/component/</id><entry><title type="html">Hugo Modules: Importing a Theme</title><link href="https://scripter.co/hugo-modules-importing-a-theme/?utm_source=atom_feed" rel="alternate" type="text/html"/><link href="https://scripter.co/hugo-modules-getting-started/?utm_source=atom_feed" rel="related" type="text/html" title="Hugo Modules: Getting Started"/><link href="https://scripter.co/looping-through-org-mode-headings/?utm_source=atom_feed" rel="related" type="text/html" title="Looping through Org mode headings"/><link href="https://scripter.co/using-org-logbook-notes-to-record-blog-post-updates/?utm_source=atom_feed" rel="related" type="text/html" title="Using Org Logbook Notes to record blog post updates"/><link href="https://scripter.co/building-org-development-version/?utm_source=atom_feed" rel="related" type="text/html" title="Building Org Development version (2022)"/><link href="https://scripter.co/downloading-nim/?utm_source=atom_feed" rel="related" type="text/html" title="Downloading Nim"/><id>https://scripter.co/hugo-modules-importing-a-theme/</id><author><name>Kaushal Modi</name></author><published>2022-05-26T16:26:00-04:00</published><updated>2022-05-26T16:26:00-04:00</updated><content type="html"><![CDATA[<blockquote>A brief guide on how to install Hugo themes using Hugo Modules.</blockquote><div class="ox-hugo-toc toc">
<div class="heading">Table of Contents</div>
<ul>
<li><a href="#clean-up-the-old-way-of-setting-a-theme"><span class="section-num">1</span> Clean up the old way of setting a theme</a></li>
<li><a href="#import-the-theme-module"><span class="section-num">2</span> Import the &ldquo;theme&rdquo; module</a>
<ul>
<li><a href="#module-imports-example">Quick Example</a></li>
</ul>
</li>
<li><a href="#hugo-mod-tidy"><span class="section-num">3</span> <code>hugo mod tidy</code></a></li>
<li><a href="#updating-the-theme"><span class="section-num">4</span> Updating the theme</a></li>
<li><a href="#dependency-graph">Dependency Graph</a></li>
<li><a href="#building-your-hugo-site-on-a-server">Building your Hugo site on a server</a></li>
<li><a href="#in-a-nutshell">In a nutshell</a></li>
<li><a href="#references">References</a></li>
</ul>
</div>
<!--endtoc-->
<p>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.</p>
<p><strong>Step 0</strong> for that approach is to make your site repo a Hugo Module. If
your site already is, then it would have a <code>go.mod</code> file in the repo
root. If you don&rsquo;t have the <code>go.mod</code> file, check out the previous post
<a href="/hugo-modules-getting-started/">Hugo Modules: Getting Started</a> first ‼️</p>
<div class="note">
<p>If you don&rsquo;t have a <code>go.mod</code> file for your site repo, and you still
decide to continue with the next steps, don&rsquo;t complain if you see
errors like <em>module &ldquo;foo&rdquo; not found; either add it as a Hugo Module or
store it in &ldquo;&lt;your site repo&gt;/themes&rdquo;.: module does not exist</em>. &mdash;
<a href="https://discourse.gohugo.io/t/hugo-mod-init-fails-to-create-go-mod-if-hugo-detects-an-error-prematurely-in-site-config-toml/36687">speaking from experience</a> 😉.</p>
</div>
<p>With that out of the way, here are the next steps ..</p>

<h2 id="clean-up-the-old-way-of-setting-a-theme"><span class="section-num">1</span> Clean up the old way of setting a theme&nbsp;<a class="headline-hash no-text-decoration" href="#clean-up-the-old-way-of-setting-a-theme">#</a></h2>


<p>If you are upgrading your Hugo site to switch from the legacy method
of using themes (i.e using the <code>theme</code> variable in the site config
<span class="sidenote-number"><small class="sidenote">
In my posts, you may have seen me use the <em>Site Config</em> term or
<code>config.toml</code> &ndash; They mean the same thing.
</small></span>
), you need to clean that up.</p>
<ol>
<li>Remove the <code>theme</code> variable from your site config.</li>
<li>Remove the <code>themes</code> directory, or move it out of your Hugo site
repo.
<ul>
<li>If you were cloning a theme developed by someone else in there,
you can just remove this directory.</li>
<li>If you are maintaining your own theme in that directory, move it
out of your site repo and <a href="/hugo-modules-getting-started/#convert-to-hugo-module">convert it to a Hugo Module</a>.</li>
</ul>
</li>
</ol>

<h2 id="import-the-theme-module"><span class="section-num">2</span> Import the &ldquo;theme&rdquo; module&nbsp;<a class="headline-hash no-text-decoration" href="#import-the-theme-module">#</a></h2>


<p>The <em>theme</em> is quoted in this title, because the concept of a Hugo
&ldquo;theme&rdquo; is a bit old now (<span class="timestamp-wrapper"><span class="timestamp">&lt;2022-05-26 Thu&gt;</span></span>) and that has been
superseded with the concept of &ldquo;modules&rdquo;.</p>
<p>The main difference between a theme and a generic <em>Hugo Module</em> 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.</p>
<div class="note">
<p>I am mentioning this again for convenience, from <a href="/hugo-modules-getting-started/">the previous post in
this series</a>:</p>
<p><em>A module can be your main project or a smaller module providing one
or more of the 7 component types defined in Hugo: <strong>static</strong>, <strong>content</strong>,
<strong>layouts</strong>, <strong>data</strong>, <strong>assets</strong>, <strong>i18n</strong>, and <strong>archetypes</strong>. You can combine
modules in any combination you like, and even mount directories from
non-Hugo projects, forming a big, virtual union file system.</em></p>
</div>
<p>A theme will need to have the &ldquo;layout&rdquo; component. Additionally, it
might have the &ldquo;assets&rdquo;, &ldquo;static&rdquo;, and other components too.</p>
<p>Importing a module as a theme will typically look like this in your
site config:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">module</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">[[</span><span class="nx">module</span><span class="p">.</span><span class="nx">imports</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl">    <span class="nx">path</span> <span class="p">=</span> <span class="s2">&#34;URL of the theme&#39;s git remote *without* the &#39;https://&#39; part&#34;</span>
</span></span></code></pre></div><p>The <strong>path</strong> here would be something like
<code>github.com/USER/THEME-REPO-NAME</code> or
<code>gitlab.com/USER/THEME-REPO-NAME</code>.</p>
<dl>
<dt>Note</dt>
<dd>It&rsquo;s possible to take <span class="underline">any</span> Hugo theme git repo and import
that as a Hugo Module even if that repo isn&rsquo;t actually one
i.e. doesn&rsquo;t have a <code>go.mod</code>. But it&rsquo;s recommended that the theme be
a proper Hugo Module so that you have better dependency tracking
between your site and the theme.</dd>
</dl>

<h3 id="module-imports-example">Quick Example&nbsp;<a class="headline-hash no-text-decoration" href="#module-imports-example">#</a></h3>


<p>Follow these steps if you want to try out how this Hugo Module based
theme importing</p>
<div class="note">
<p>As a reminder, you <a href="/hugo-modules-getting-started/#install-a-recent-version-of-go">need to have Go installed</a>
on your system.</p>
</div>
<ol>
<li>Create a temporary directory somewhere and <code>cd</code> to it.</li>
<li>Initialize your site as a Hugo Module: <code>hugo mod init foo</code> (yeah,
type that out literally &mdash; it will work)</li>
<li>Create a <code>config.toml</code> file with the below content. It imports the
<a href="https://gitlab.com/kaushalmodi/hugo-mwe-theme"><code>hugo-mwe-theme</code></a>
<span class="sidenote-number"><small class="sidenote">
<code>hugo-mwe-theme</code> is a minimal Hugo theme that I use to quickly try
out some new feature in Hugo or to create a <em>minimal working
example</em> to reproduce a bug.
</small></span>
theme.
<a id="code-snippet--theme-module-import-example"></a>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">module</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">[[</span><span class="nx">module</span><span class="p">.</span><span class="nx">imports</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl">    <span class="nx">path</span> <span class="p">=</span> <span class="s2">&#34;gitlab.com/kaushalmodi/hugo-mwe-theme&#34;</span>
</span></span></code></pre></div><div class="src-block-caption">
  <span class="src-block-number"><a href="#code-snippet--theme-module-import-example">Code Snippet 1</a>:</span>
  Example of importing a Hugo module as a theme in <code>config.toml</code>
</div>
</li>
<li>Create <code>content/hello.md</code>. This step is optional and is only so
that your test site as some content.
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl">+++
</span></span><span class="line"><span class="cl">title = &#34;Hello&#34;
</span></span><span class="line"><span class="cl">+++
</span></span><span class="line"><span class="cl">Hey!
</span></span></code></pre></div></li>
</ol>
<p>That&rsquo;s it! Now run the Hugo server (<code>hugo server</code>) and look at your
site running on localhost .. while thinking in disbelief.. <em>just how
easy all of this was!</em> 😃.</p>
<ul>
<li>Did you need to manually clone any theme? <strong>No</strong></li>
<li>Would you need to deal with the <code>.gitmodules</code> file? <strong>No</strong></li>
</ul>

<h2 id="hugo-mod-tidy"><span class="section-num">3</span> <code>hugo mod tidy</code>&nbsp;<a class="headline-hash no-text-decoration" href="#hugo-mod-tidy">#</a></h2>


<p>Finally, run <a href="https://gohugo.io/commands/hugo_mod_tidy/"><code>hugo mod tidy</code></a> to clean up the <code>go.mod</code> and
update/generate the <code>go.sum</code> file. These files will track the module
dependencies for your site.</p>
<ul>
<li>The <code>go.mod</code> contains the direct module dependencies for your site.</li>
<li>The <code>go.sum</code> contains the versions and hashes of all the direct <strong>and
indirect</strong> dependencies
<span class="sidenote-number"><small class="sidenote">
Just as you added a theme as a Hugo Module to your site, it&rsquo;s
possible that that theme is depending on other Hugo Modules (like
the ones I mentioned earlier: ATOM feeds, search, etc.).
</small></span>
for your site.</li>
</ul>
<div class="note">
<p>You would need to commit the <code>go.mod</code> and <code>go.sum</code><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> files if you
build and deploy your website on a remote server or a <a href="https://en.wikipedia.org/wiki/CI/CD">CI/CD</a> system.</p>
</div>
<p>If you ran the <a href="#module-imports-example">Quick Example</a>, you will see this (as of
<span class="timestamp-wrapper"><span class="timestamp">&lt;2022-05-26 Thu&gt;</span></span>) in your <code>go.mod</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">module foo
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">go 1.18
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">require gitlab.com/kaushalmodi/hugo-mwe-theme v0.1.1 // indirect
</span></span></code></pre></div><p>.. and this in your <code>go.sum</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">gitlab.com/kaushalmodi/hugo-mwe-theme v0.1.1 h1:FyTp43CJRpBfoHyWnwQFx//cipgP6xQ9/uucj+qjj1U=
</span></span><span class="line"><span class="cl">gitlab.com/kaushalmodi/hugo-mwe-theme v0.1.1/go.mod h1:vvq0r/SfKMbiPbyqL4YottSOkpCkBSosqGRm82aDNrU=
</span></span></code></pre></div>
<h2 id="updating-the-theme"><span class="section-num">4</span> Updating the theme&nbsp;<a class="headline-hash no-text-decoration" href="#updating-the-theme">#</a></h2>


<p>Here are some common ways to update the theme module going forward:</p>
<table>
<thead>
<tr>
<th>Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>hugo mod get -u</code></td>
<td>Update only the modules that your site directly depends on.</td>
</tr>
<tr>
<td><code>hugo mod get -u ./...</code></td>
<td>Update the modules that your site depends on in a recursive fashion.</td>
</tr>
</tbody>
</table>
<p>Additionally, you might or might not need these, but I am documenting
them here for completeness:</p>
<table>
<thead>
<tr>
<th>Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>hugo mod get -u &lt;module path&gt;</code></td>
<td>Update only the specified module<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> to the latest version. Example: <code>hugo mod get -u gitlab.com/kaushalmodi/hugo-mwe-theme</code></td>
</tr>
<tr>
<td><code>hugo mod get &lt;module path&gt;@&lt;git ref&gt;</code></td>
<td>Update a module to the specified git tag or commit. Example: <code>hugo mod get gitlab.com/kaushalmodi/hugo-mwe-theme@v0.1.1</code></td>
</tr>
</tbody>
</table>

<h2 id="dependency-graph">Dependency Graph&nbsp;<a class="headline-hash no-text-decoration" href="#dependency-graph">#</a></h2>


<p>If you have a theme added as a Hugo Module, which depends on other
Hugo Modules, it&rsquo;s often helpful to know the dependency graph. You can
do that by running:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">hugo mod graph
</span></span></code></pre></div><p>For the above <a href="#module-imports-example">Quick Example</a>, you will see just this one line because
that theme does not depend on other modules:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">foo gitlab.com/kaushalmodi/hugo-mwe-theme@v0.1.1
</span></span></code></pre></div>
<h2 id="building-your-hugo-site-on-a-server">Building your Hugo site on a server&nbsp;<a class="headline-hash no-text-decoration" href="#building-your-hugo-site-on-a-server">#</a></h2>


<p>Alright, so you are able to build your site locally after switching to
using themes as modules, great!</p>
<p>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.</p>
<p>I deploy this website using Netlify, and so I know how to do that
there &mdash; Set the <code>GO_VERSION</code> environment variable to a recent
version like <strong>1.18</strong> in the <a href="https://docs.netlify.com/configure-builds/environment-variables/">Environment variables</a> section in Netlify
<em>Build &amp; deploy</em> settings.</p>

<h2 id="in-a-nutshell">In a nutshell&nbsp;<a class="headline-hash no-text-decoration" href="#in-a-nutshell">#</a></h2>


<ol>
<li><strong>First</strong> convert your Hugo site to a Hugo module.</li>
<li>Then replace the <code>theme</code> in your site config with a module import.</li>
</ol>
<p>Enjoy! 🍾</p>

<h2 id="references">References&nbsp;<a class="headline-hash no-text-decoration" href="#references">#</a></h2>


<ul>
<li><a href="https://gohugo.io/hugo-modules/use-modules/">Hugo Modules documentation</a></li>
<li><a href="https://www.thenewdynamic.com/article/hugo-modules-everything-from-imports-to-create/">Hugo Modules: Everything you need to know!</a></li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>It is recommended to <em>git commit</em> the <code>go.sum</code> along with your
site&rsquo;s <code>go.mod</code>. From the <a href="https://github.com/golang/go/wiki/Modules#releasing-modules-all-versions">Go Modules documention</a>: <em>Ensure your
<code>go.sum</code> file is committed along with your <code>go.mod</code> file. See <a href="https://github.com/golang/go/wiki/Modules#should-i-commit-my-gosum-file-as-well-as-my-gomod-file">FAQ
below</a> for more details and rationale.</em>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Trust me.. once you get a hang of the Hugo Module system, your
site will have more than one!&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content><category scheme="https://scripter.co/categories/hugo" term="hugo" label="hugo"/><category scheme="https://scripter.co/series/hugo-modules" term="hugo-modules" label="Hugo Modules"/><category scheme="https://scripter.co/tags/module" term="module" label="module"/><category scheme="https://scripter.co/tags/100daystooffload" term="100daystooffload" label="100DaysToOffload"/><category scheme="https://scripter.co/tags/theme" term="theme" label="theme"/><category scheme="https://scripter.co/tags/component" term="component" label="component"/></entry></feed>