When building a multilingual Hugo site, translating taxonomy terms like tags adds a polished touch for your readers. A common problem: you want to show tags in the visitor’s language on listing and detail pages, but you don’t want to manually translate or duplicate taxonomy values in every content file front matter.
Here’s how you can leverage Hugo’s i18n system for tag translations, without editing the front matter in every local content file.
1. Don’t Translate Taxonomy in Front Matter
Keep your front matter minimal and language-agnostic when possible:
+++
title = "AI and Beatmaking"
date = 2025-06-02
tags = ["AI_Beatmaking", "Beatmaker_Mindset", "Consistency"]
+++
Use keys that are easy to maintain, no need to write Japanese tags in ja.md or English tags in .md. This keeps your content files less error-prone and easier to reuse.
2. Create i18n Translation Files
Create language-specific TOML files under your i18n folder. For example:
- i18n/en.toml
- i18n/ja.toml
Each entry will look like this in en.toml:
[AI_Beatmaking]
other = "AI Beatmaking"
[Beatmaker_Mindset]
other = "Beatmaker Mindset"
[Consistency]
other = "Consistency"
And like this in ja.toml:
[AI_Beatmaking]
other = "AIビートメイキング"
[Beatmaker_Mindset]
other = "ビートメイカー・マインドセット"
[Consistency]
other = "一貫性"
Add translations for every tag you want displayed in each language.
3. Update Templates to Use i18n
In your Hugo templates
(for example, post_preview.html and single.html)
you can display tags in the visitor’s language using both the i18n translation files and your tag list in front matter. Here’s an example based on my implementation:
{{ if .Params.tags }}
<div class="blog-tags">
{{ range .Params.tags }}
{{ $key := . | replaceRE "[- ]" "_" }}
<a href="{{ "tags" | absLangURL }}/{{ . | urlize }}/">{{ i18n $key | default . }}</a>
{{ end }}
</div>
{{ end }}
What’s happening here:
Key Standardization:
{{ $key := . | replaceRE "[- ]" "_" }}
This line ensures any tag containing spaces or hyphens is converted to use underscores
(e.g.
AI Beatmaking or
AI-Beatmaking →
AI_Beatmaking).
This format will reliably match the keys you use in your i18n TOML files.
Link Generation & URL Safety:
{{ . | urlize }}
Generates clean, lowercase, and URL-friendly slugs for your tag archive links.
Translation with Fallback:
{{ i18n $key | default . }}
Checks the translation in the current language’s i18n file; if no translation is found, it falls back to displaying the original tag value as a safety net.
This will look up .Params.tags (array like [“AI_Beatmaking”, “Beatmaker_Mindset”, “Consistency”]), and display “AIビートメイキング” or “ビートメイカー・マインドセット” or “一貫性” etc., using the current language’s i18n file.
4. No Need to Touch Front Matter
This approach means your content files stay simple and language-agnostic. Hugo dynamically selects the right translation for tags based on the current language, using the keys set in your i18n files.
5. (Optional) Keep/Remove en.toml
You can keep or remove en.toml:
- If you remove it, Hugo will just output the raw tag key in English mode.
- If you keep it, you control how tags look in English, e.g., formatting, spaces, or more readable capitalization.
Benefits of This Approach
- One Source of Truth: All translations in one place—easy to update.
- Less Error-Prone: No repeated/duplicated translations in individual content files’ front matter.
- Scalable: Add new languages or tags without hunting through all your posts.
Example of Complete Tag Usage in Template:
<ul>
{{ range .Params.tags }}
{{ $key := . | replaceRE "[- ]" "_" }}
<li>
<a href="{{ "tags" | absLangURL }}/{{ . | urlize }}/">{{ i18n $key | default . }}</a>
</li>
{{ end }}
</ul>
Result:
- On the English site:
“AI Beatmaking,” “Beatmaker Mindset,” “Consistency” - On the Japanese site:
“AIビートメイキング,” “ビートメイカー・マインドセット,” “一貫性”
Each tag is automatically translated according to the i18n TOML files and linked to the appropriate tag archive URL, with a fallback to the original tag if no translation exists. No translation in the content front matter is needed.
Conclusion
By storing tag translations in the i18n folder and referencing them in your templates, you keep your site modular, maintainable, and ready for growth, all without cluttering your front matter with language-specific values.
Leave a Reply