Hugo File Loading Order
Hugo’s File Loading Order: Project vs. Theme#
Hugo follows a priority system when reading files:
- Project-level files (your custom files)
- If a file exists in your project (
layouts/partials/header.html
), Hugo uses that first.
- If a file exists in your project (
- Theme-level files
- If the file isn’t in your project, Hugo looks in the theme (
themes/mytheme/layouts/partials/header.html
).
- If the file isn’t in your project, Hugo looks in the theme (
- Hugo defaults
- If no file exists in either place, Hugo may use a built-in default (rare but possible).
This means:
- If you copy
header.html
intolayouts/partials/
, Hugo will use that version instead of the theme’s. - If you don’t copy
header.html
, it will fall back to the theme’s version. - If the theme doesn’t have a
header.html
, Hugo just won’t include one.
Front Matter & Archetypes#
Using archetypes is better than manually adding front matter to every .md
file.
Why?#
- Saves time—pre-fills front matter automatically.
- Ensures consistency—avoids missing or inconsistent fields.
How Many Archetypes Can You Have?#
As many as you want.
Types of Archetypes:#
Global Default (
archetypes/default.md
)- Used when no section-specific archetype exists.
Section-Specific (
archetypes/blog.md
,archetypes/projects.md
)Used when creating content inside a matching section.
Example:
hugo new blog/my-post.md # Uses archetypes/blog.md
Custom Archetypes
You can define multiple archetypes for different content types.
Example:
archetypes/ ├── default.md ├── blog.md ├── project.md ├── event.md
Then, create content using:
hugo new blog/my-article.md # Uses blog.md hugo new project/new-website.md # Uses project.md hugo new event/conference.md # Uses event.md
Customizing the Header While Keeping the Rest of the Theme#
If you only want to modify the header but keep everything else from the theme, Hugo will automatically merge your custom file with the theme.
How Hugo Loads Files in This Case#
- It first looks for
layouts/partials/header.html
in your project.- If found, it uses this file instead of the theme’s.
- For everything else, it keeps using the theme files.
- Example:
layouts/partials/footer.html
will still come from the theme unless you override it.
- Example:
How to Do It Step by Step#
1. Copy Just the Header Partial#
Run this in your project root:
mkdir -p layouts/partials
cp themes/mytheme/layouts/partials/header.html layouts/partials/header.html
- This overrides only the header, leaving all other theme files untouched.
2. Modify the Header#
Now, edit layouts/partials/header.html
however you like.
What If the Header Calls Other Theme Files?#
If the theme’s header.html
includes other theme partials, like:
{{ partial "nav.html" . }}
- Hugo will first check for
layouts/partials/nav.html
in your project. - If it doesn’t exist, it will fallback to
themes/mytheme/layouts/partials/nav.html
.
Alternative: Extending Instead of Overriding#
Instead of copying and modifying the entire header.html
, you can modify only a part of it while keeping the theme structure.
Example: Using Blocks Inside the Header#
If your theme’s header.html
has this:
<header>
<h1>{{ .Site.Title }}</h1>
{{ block "custom_header" . }}{{ end }}
</header>
Then in your project’s layouts/partials/header.html
, you can just do:
{{ define "custom_header" }}
<p>Custom message here!</p>
{{ end }}
This method is cleaner because:
- You don’t have to replace the entire file.
- If the theme updates, your customizations still work.