Extending a Hugo Theme Without Overwriting It#

Extending means modifying only specific parts of a theme while keeping the rest intact. Instead of fully overriding a file, you inject your changes where the theme allows.


1. How Hugo Extends Themes#

Hugo uses blocks, partials, and hooks to allow customization without replacing entire files.

  • Blocks (baseof.html) – Let you modify content inside a theme’s base layout.
  • Partials (partials/*.html) – Let you modify specific sections (e.g., header, footer).
  • Hooks (custom-defined blocks) – Some themes define specific “hook” areas for injecting content.

2. Using Blocks to Extend Theme Layouts#

Many Hugo themes use baseof.html as a master template.
Inside this file, they define blocks, which child layouts (like single.html, list.html) can modify.

Example: baseof.html in the Theme#

<!DOCTYPE html>
<html lang="en">
<head>
    <title>{{ .Title }}</title>
</head>
<body>

    {{ partial "header.html" . }}

    <main>
        {{ block "main" . }}{{ end }}
    </main>

    {{ partial "footer.html" . }}

</body>
</html>

The {{ block "main" . }}{{ end }} lets child layouts inject their own content.

How You Extend It#

You create layouts/_default/single.html and modify only the main block:

{{ define "main" }}
<article>
    <h1>{{ .Title }}</h1>
    <p>{{ .Content }}</p>
</article>
{{ end }}

This way, the header, footer, and structure stay the same, but your content is custom.


3. Extending Theme Partials Without Overwriting#

Instead of replacing a whole header.html, you can inject modifications using a custom block.

Step 1: Check If Your Theme Supports Hooks#

Some themes define custom blocks inside partials:
Example in a theme’s header.html:

<header>
    <h1>{{ .Site.Title }}</h1>
    {{ block "custom_header" . }}{{ end }}
</header>
  • If you see a block like this, you can extend it!
  • If not, you may have to override the file manually.

Step 2: Extend It in Your Project#

Create a file in layouts/partials/header.html:

{{ define "custom_header" }}
    <p>Welcome to my site!</p>
{{ end }}
  • This adds content inside the theme’s header without replacing it.

4. How to Extend a Theme That Doesn’t Have Blocks?#

If a theme doesn’t have blocks, you may need to:

  1. Override the file completely (not ideal).
  2. Modify the theme to add a block (best approach for long-term flexibility).

Adding Blocks to a Theme (If Missing)#

  1. Find the theme’s header.html file.

  2. Modify it inside themes/mytheme/layouts/partials/header.html:

    <header>
        <h1>{{ .Site.Title }}</h1>
        {{ block "custom_header" . }}{{ end }}
    </header>
    
  3. In your project, create layouts/partials/header.html and define the block:

    {{ define "custom_header" }}
        <p>Custom content here!</p>
    {{ end }}
    

This ensures future theme updates won’t break your changes.


5. Summary of Extending vs. Overwriting#

MethodDescriptionBest Use Case
OverridingCopying a full file from the theme into your project and modifying itIf no other option exists, but it makes updates harder
Blocks (define)Injecting content into predefined areas of a layoutWhen themes already support blocks (like baseof.html, header.html)
Extending partialsModifying only parts of a theme’s header, footer, or other componentsIf a theme provides hook points for customization