Tweaking Hugo Themes: Adding a Multilingual Custom Footer
How to safely override theme layouts and reuse social configuration in the LoveIt theme.

Making Hugo Themes Your Own
Building a site with Hugo is like moving into a pre-furnished, designer apartment. It looks great the moment you step in, but it doesn’t truly feel like home until you hang your own art on the walls or swap out the rug.
The LoveIt theme is widely loved for its clean aesthetic, built-in search, and dark mode support. However, generic footers or standard layouts can make your corner of the internet feel a bit “out of the box.” Whether you want to add a unique copyright notice, a custom “Buy Me a Coffee” link, or specific tracking scripts, tweaking the theme is the best way to inject your personality into your technical blog.
In this guide, we’ll move past the basic hugo.toml settings and look at how to safely modify the underlying structure without breaking the ability to update your theme later.
2. Under the Hood: How Hugo Themes (and Overrides) Work
Before we touch the code, it’s important to understand the Hugo Lookup Order. Think of Hugo as a search engine looking for instructions on how to render your site.
The Hierarchy of Power
When Hugo builds your site, it looks for files (layouts, archetypes, and assets) in a specific order of priority:
- Your Project Root (
/layouts,/assets): This is the highest priority. - The Theme Folder (
/themes/LoveIt/layouts, etc.): This is the fallback.
The “Override” Pattern
The golden rule of Hugo development is: Never edit files directly inside the themes/ folder. If you modify the theme files directly, your changes will be wiped out the next time you update the theme via Git submodules or a zip download. Instead, we use the Override Pattern:
- Identify: Find the file you want to change inside
themes/LoveIt/layouts/... - Replicate: Create an identical folder structure in your root directory.
- Modify: Copy the file into your root directory and edit it there.
Because your root directory has a higher priority, Hugo will see your version of the file and say, “Aha! I’ll use this custom version instead of the default one in the theme folder.”
What We’re Building
Before we dive into the code, here is a quick overview of the custom footer system we are implementing for the LoveIt theme:
- Multilingual Support: Automatically displays content in English or German based on the post’s language.
- Automatic Social Integration: Reuses the PayPal, Patreon, or GitHub Sponsors links already defined in your
hugo.toml. - Theme Consistency: Uses LoveIt’s internal plugins so icons and styles match your site perfectly.
- Smart “Opt-Out” Control: The footer appears on all posts by default, but can be disabled on a per-post basis by adding
add_custom_footer: falseto your Front Matter.
Step 1: Overriding the Post Layout
First, we copy the theme’s post template to our root directory. In LoveIt, this is located at themes/LoveIt/layouts/posts/single.html. Copy it to:
layouts/posts/single.html
Inside this file, we inject a logic block where we want the footer to appear (usually after the content section):
{{- /* Custom Footer Logic */ -}}
{{- if ne .Params.add_custom_footer false -}}
<div class="post-footer-custom">
<hr>
{{- $footerPath := printf "custom/footer-%s.html" .Lang -}}
{{- if templates.Exists (printf "_partials/%s" $footerPath) -}}
{{- partial $footerPath . -}}
{{- else -}}
{{- /* Fallback to German if the specific language file is missing */ -}}
{{- partial "custom/footer-de.html" . -}}
{{- end -}}
</div>
{{- end -}}{{- if ne .Params.add_custom_footer false -}}allows you to opt-out when you have add_custom_footer: false set in the articles Front Matter.You might notice that our logic includes a fallback to footer-de.html. This is intentional!
In many Hugo setups, the default language (in this case, German) is configured to appear at the root of the URL (e.g., example.com/post-title/) rather than under a language-specific prefix like /de/.
Because Hugo doesn’t always explicitly “stamp” the root-level files with a language-specific path in the same way it does for translated sub-directories (like /en/), using a fallback ensures that even if the language detection doesn’t return a specific string, your readers still see your preferred default footer.
Step 2: Creating the Language Partials
Now, create the content for your footer. By using .Lang, Hugo automatically detects if the post is /en/ or /de/ and picks the right file.
File: layouts/_partials/custom/footer-en.html
<div class="custom-post-footer">
<h4>Thoughts or Questions?</h4>
<p>I'd love to hear your feedback! Feel free to share them below or leave a reaction.</p>
<h4>Support My Work</h4>
<div class="support-wrapper">
{{- partial "custom/support-links.html" . -}}
</div>
<hr>
</div>File: layouts/_partials/custom/footer-de.html
<div class="custom-post-footer">
<hr>
<h4>Lust auf Austausch?</h4>
<p>Hat dir dieser Beitrag geholfen? Ich freue mich riesig über dein Feedback, Fragen oder auch einfach ein kurzes „Hallo“ in den Kommentaren. Dein Input motiviert mich und hilft dabei, die Inhalte stetig zu verbessern!</p>
<h4>Meine Arbeit unterstützen</h4>
<p>Diesen Blog zu pflegen kostet Zeit und jede Menge Kaffee. Wenn dir meine Artikel gefallen, freue ich mich über eine kleine Unterstützung. Das hilft mir dabei, das Projekt werbefrei zu halten und regelmäßig neue Inhalte zu liefern!</p>
<div class="support-wrapper">
{{- partial "custom/support-links.html" . -}}
</div>
</div>Step 3: Reusing Theme Social Config
This is the “pro” move. Instead of hardcoding links, we create layouts/_partials/custom/support-links.html to pull from your hugo.toml parameters.
We filter your existing social list for specific “support” keys (like PayPal or Patreon) and pass them through LoveIt’s internal social plugin so they stay styled consistently with the rest of the theme:
<div class="support-links">
{{- $socialMap := resources.Get "data/social.yml" | transform.Unmarshal -}}
{{- $supportServices := slice "paypal" "patreon" "ko-fi" "githubsponsor" "liberapay" -}}
{{- range $key, $value := .Site.Params.social -}}
{{- if in $supportServices ($key | lower) -}}
{{- $social := $key | lower | index $socialMap | default dict -}}
{{- if $value -}}
{{- if reflect.IsMap $value -}}
{{- $social = merge $social $value -}}
{{- else -}}
{{- $social = dict "Id" $value | merge $social -}}
{{- end -}}
{{- partial "plugin/social.html" $social -}}
{{- end -}}
{{- end -}}
{{- end -}}
</div>4. Styling: Making it “Snug”
To ensure the headlines and paragraphs look like a single unit, add this to your assets/css/_custom.scss:
/* Custom Post Footer Styling */
.custom-post-footer {
margin-top: 2rem;
}
.custom-post-footer h4 {
margin-bottom: 0.4rem; /* Tighten space below headline */
color: var(--title-color);
}
.custom-post-footer p {
margin-top: 0; /* Remove top gap of paragraph */
margin-bottom: 1rem;
}
.support-wrapper {
margin-top: 0.8rem;
display: flex;
gap: 12px;
}Conclusion
By leveraging the Override Pattern and Hugo’s .Lang variable, we’ve created a dynamic, multilingual footer that feels like a native part of the LoveIt theme. Not only is it future-proof against theme updates, but it also provides a professional way to connect with your readers and sustain your work.
Happy Coding!