Articles, Expert to expert

Drupal 8 translations best practices

Hannes Kirsman
By Hannes Kirsman

Drupal 8 logo

Multilingual sites are more and more common nowadays, at least a requirement in most of the projects we build. That’s why I wanted to create a list of tips for developing a multilingual Drupal 8 site. All the tips are about translations, and yes, this post is going to the technical bits.

Hide untranslated nodes from the menu

When multilingual sites are concerned, we often come across a solution where the main language has the most content and translations cover only a certain amount of it. Sometimes the structure might vary too. This makes maintaining the translations and language versions trickier, as everything isn’t exactly the same between the languages.

One solution with Drupal 8 is to create separate menus for all the languages but then you can’t use the node translation – menu parent is a shared field. This means that if you change the menu path in English, all the other nodes get the same change. This approach would also make the ‘Language switcher’ feature – which allows easy switching between the active content (eg. switch between ‘About us’ pages in different languages) – unusable.

Another option would be to use “Content Language Access”. It’s one of the proposed solutions at the moment but I see it has a drawback too: while untranslated menus are not shown to anonymous users, they are still shown when logged in as an editor. You can just imagine the mess this creates for content editors. In worst cases, if there’s no room for links, the whole site could break.

We used it during most of the development period of one project, but then months later I did another research round and found a sandbox module that worked exactly the way we needed. No more untranslated menu items – logged in or not. The module was just recently promoted to full project and it’s called “Menu block current language”. Remember that you still need to replace the core menu blocks with ones that the module offers and there might be minor HTML changes – block id and class – so you also might need to adjust your CSS a little bit.

Fixing core bug: translations of field labels are reset to the default language

You might have noticed that when you translate field labels, they lose translation after cache rebuild. Also, the labels don’t change before the original label translation is re-saved. Translations are still there in the database but the site is displaying original language.

Obviously this can be confusing, and take some serious debugging time.

Good news is that it’s actually a core bug which has a solution. You can read more about it from here For Drupal 8.3.x we’re using

Manage the UI translations yourself

I would recommend this because it’s pretty complicated. You translate your:

  • forms from admin/structure/webform/manage/FORM-NAME/translate,
  • views from admin/structure/views/view/YOUR-VIEW-NAME/translate,
  • taxonomy label from admin/structure/taxonomy/manage/TAX-NAME/overview/fields/FIELD/translate/et/edit
  • general translations from admin/config/regional/translate
  • and last but not least, your custom code directly from Drupal source.

And this is actually a bigger list if you include all the possible UI strings.

Easy to miss: Drupal can export configuration in the wrong langcode

Drupal 8 can now export its configuration to YAML files. That’s awesome! Still one tip: on the second line in these files you can find a variable called langcode. In theory, it should always have the same value in all the configuration files, but in reality, Drupal likes to set it based on which language the site had when it was first configured in the admin environment. Although it should be agreed to always configure the site in the source language, it’s easy to miss from time to time. To be sure, you should occasionally check the YAML files and always review commits. If you find any mistakes, change them directly from the YAML file and re-import the configuration. As a side note – we always use English as the default language (admin/config/regional/language) so then it’s good to check that the langcode variable is “en”.

Lessons learned

Translations are a tricky thing, and I haven’t come across a perfect solution yet. However, Drupal is doing well with this, considering that Drupal 8 is still quite a new player. Contrib land (read custom modules) is evolving, and core is getting better and better! So all in all I recommend:

Hopefully, you found the tips useful! If you have any comments or other tips, I’m very interested in hearing those. Just send me an email.