We do not expect you to translate themes to multiple languages, but the theme should be translatable. It means that all strings in the template files should be translatable. This is a requirement if you are planning to publish the theme.

If you are creating a private theme for a single language blog, you may skip this part.

Internationalization is easy. Instead of writing this:


You have to write this:

<h1>{{ 'welcome' | lang }}</h1>

Here, 'welcome' is a key in en.yaml. And, lang is a custom Twig filter defined by HB. HB will display the correct language based on the language of the user's blog.

Lang folder

The /lang folder contains .yaml language files. A language file may look like this:

welcome: Welcome

English is required

English (en.yaml) is the default language and it is required. You may also define other languages. Language codes should be ISO 639-1 Codes.

Let's see another example:

welcome: "Welcome to our blog"
usersCount: "* users"
byAuthor: "by {authorName}"

In Twig templates, use the lang filter to render these strings with placeholders replaced.

    {{ 'welcome' | lang }}

<p>{{ 'byAuthor' | lang( }}</p>

<p>{{ 'usersCount' | lang(2) }}</span>

As you can see there are two placeholders types:

Conditional strings based on a number

Sometimes you may want to display a different message when a number is zero, one, or more than one. Instead writing a bunch of if conditions, you may use the lang_by_number custom Twig filter.

# en.yaml
posts_num_zero: No Posts
posts_num_one: 1 Post
posts_num_multi: "* Posts"
Number of posts: 
{{ | lang_by_number(
) }} is a number. The * in posts_num_multi will be replaced by the given number.

How translations work

You may take a look at the languages guide. It explains how to change the language or set up multiple languages in a blog.

Let's say that the blogger changes his site's language to French (fr). Then, we check if a fr.yaml is available in the lang folder. If not, we'll just show English strings. However, anyone can easily add a fr.yaml from the Console (even someone without technical knowledge can do that). Keys don't change, only the strings.

Here's how an fr version of the above file will look like.

welcome: "Bienvenue sur notre blog"
usersCount: "* utilisateurs"
byAuthor: "par {authorName}"

DO NOT use nested keys in YAML language files. Keep it to simple key-value pairs.

Language switcher

Usually, you want to render a language switcher in multi-language blogs to allow visitors to switch between languages.

{% if _blog.languages | length > 1 %}
        function toggleLanguageDropdown() {
    <div class="language-switcher">
        <a class="current-language" onclick="toggleLanguageDropdown()">{{ _lang.code }}</a>
        <div class="dropdown">
            {% for lang in _blog.languages %}
                    href="{{ lang.code | language_variant_url }}"
                    class="{% if lang.code == _lang.code %}active{% endif %}"
                >{{ }}</a>
            {% endfor %}
{% endif %}