Definition of Extending in Hugo#

Extending a theme means modifying or adding to its functionality without replacing entire files. You do this by:

  1. Using blocks ({{ block "name" . }}) inside baseof.html or other templates.
  2. Overriding specific parts of a theme by placing modified versions in your project.
  3. Using Hugo’s lookup order, which prefers your custom files over theme files.

Key Point: Hugo will ignore the theme’s file if you fully override it. But if the theme supports blocks, you can extend it without fully replacing it.


How Hugo Decides What to Use (Override vs. Extend)#

1. If You Fully Override a File (Replacement)#

  • If you put layouts/partials/header.html in your project, Hugo completely ignores themes/theme-name/layouts/partials/header.html.
  • This is a full override, not an extension.

2. If the Theme Supports Blocks (True Extension)#

If the theme’s header.html has a block:

<header>
    <h1>{{ .Site.Title }}</h1>
    {{ block "custom_header" . }}{{ end }}
</header>

You can extend it in layouts/partials/header.html like this:

{{ define "custom_header" }}
    <p>My custom text in the header.</p>
{{ end }}
  • Hugo keeps the theme’s original header.html and adds your content inside the custom_header block.

3. If the Theme Does NOT Have Blocks?#

If header.html does not have blocks, you must modify the theme file itself or override it entirely.

  • To prevent this, add your own block inside the theme file.
  • This way, future modifications can happen without fully replacing the file.

How to Ensure Reproducibility (Easy Setup on New Machines)#

To make sure your modifications always work on any machine, follow these steps:

1. Keep the Theme as a Git Submodule#

git submodule add https://github.com/theme-author/theme-name.git themes/theme-name

This ensures you don’t modify the theme directly.

2. Override Only Necessary Files#

Instead of modifying the theme itself, copy only what you need:

mkdir -p layouts/partials
cp themes/theme-name/layouts/partials/header.html layouts/partials/header.html

Modify the copied file only if necessary.

3. Use Blocks Instead of Full Overrides (If Possible)#

If the theme has baseof.html, use:

{{ define "main" }}
    <h1>Custom Content</h1>
    {{ block "main" . }}{{ end }}
{{ end }}

This keeps the theme structure intact while allowing custom content.

4. Ensure Easy Setup on a New Machine#

When cloning your project on a new machine, run:

git clone https://github.com/yourname/your-hugo-site.git
cd your-hugo-site
git submodule update --init --recursive

This restores your site with all theme modifications intact.


Final Answer: When Will Hugo Ignore the Theme File?#

  • If you put a full copy in your project (layouts/partials/header.html) → Hugo ignores the theme’s version.
  • If the theme has blocks and you define only the block in your project → Hugo keeps the theme’s file and adds your content.
  • If you modify the theme’s header.html directly → Your changes will be lost when the theme updates unless you track them in Git.

Summary#

MethodTheme Updates Safe?Keeps Theme Functionality?Works on Any Machine?
Override full file❌ No❌ No✅ Yes
Extend using blocks✅ Yes✅ Yes✅ Yes
Modify theme directly❌ No✅ Yes❌ No
Fork theme & modify✅ Yes✅ Yes✅ Yes, but harder

Would you like help checking if your theme supports blocks so you can extend instead of override?