Peter Nordmark in Development

Create a truly multilingual social platform

Haaartland aim to take over the world and be the heavy hitter in the new generation of community platforms. That means we have to be capable of presenting our user interfaces in all languages. Since we are using NuxtJS and VueJS for our UI there is existing excellent tooling for this but there is still a lot to consider when you need to deal with many languages and have to implement all aspects of i18n(internationalization and localization)

The goal

Our strategy is to support any local language in markets where we see opportunity. Today we can add a new language in days and we support all writing systems. Left-to-right, right-to-left, Arabic, Chinese, and so forth.

Starting small

We started small of course supporting only English during the initial construction of the platform. This made sense since it brings the development speed up. As soon as we were content with the overall structure of the platform we wanted to bring in a second language to test the selected i18n framework (vue-i18n). As most of us are Swedish speaking we chose Swedish as our second language. We didn't want to go bananas and add a bunch of languages at the start since we were pretty sure there will be challenges along the way.

We started by placing all the translations in their respective components. A VueJs application is based around isolated components. For instance, a Save button might be a component and we started by placing all the translations for the button in the component file. That seemed logical at the time. HTML, CSS, code, and translations all in one place. The drawback of course is that many components will have overlapping translations. Common expressions will be duplicated many times in a big project.

First real challenge

Some of our customers are big in the Middle East so pretty early on we got the request to add Arabic as a choice. Arabic is written right to left which not only forces us to add the translations, we must also adjust the whole UI to Arabic speakers. The means for instance that an English speaker expects a button on the right side of a text input field whereas the Arabic speaker expects it on the left.

This is a challenge! When the user selects Arabic we have to flip the entire UI on the X-axis.

Flippin it

We came up with a pretty neat solution to flip a UI on the x-axis. In short, the UI is built using flexboxes. When a user selects a right-to-left language we reverse all the flex items in each row and also adjust the margins to keep the correct spacing. Basically, all classes we use for positioning on the X-axis are reversed using CSS like in this example:

/* reverse flex direction */
[dir="rtl"] .flex-row {
	flex-direction: row-reverse;
[dir="ltr"] .flex-row {
	flex-direction: row;

/* reverse margins */
[dir="rtl"] .mie-16 {
	margin-left: 4rem;
[dir="ltr"] .mie-16 {
	margin-right: 4rem;

/* used to flip direction sensitive icons like a speech bubble */
[dir='rtl'] .rtl-flip-x {
    transform: scaleX(-1);

Tip: There is excellent support for handling RTL in TailwindCSS.

Growing too large

At this point we had 3 languages supported. English, Swedish, and Arabic. The platform kept on growing. Meaning more and more translations spread out in hundreds of components. We could still keep working efficiently since we were just adding stuff and translations came in incrementally.

We are now at a point where we need to support many, many more languages. It is impossible to do all these translations in-house and we need to have translators that can work efficiently. Hence, having the translations spread out over hundreds of files did not make sense anymore.

We decided to move all the translations out of the components to a single file per language. This makes it easy to send the English (default)version to a translation firm which then can translate it to whatever language. An added benefit is that we got rid of duplicates in the process.

We can now add a new language in days!

Other lessons learned

#1 Don't forget about date, time, and number formatting. Especially relative timestamps have to be dealt with. Eg. "just now", "3 seconds ago", "1 hour ago". We are using DayJS for this which has excellent support for i18n.

#2 Pluralization also needs special attention. "2 apple" does not look good so you should pay attention to handling single and plural forms. Eg. "one apple", "2 apples".

#3 Use logical translation keys. For instance, the key "common_action_save" could have the "Save" word as a value and uses for Save buttons and commands. The "views_login_helptext" might have a value with a help text only used on the login screen.

#4 Not all translations are static, make sure your selected framework can handle translating dynamic texts like "Hi {name}!" where the name placeholder is replaced with a real name that is determined at runtime.

I hope you enjoyed the read! Let me know what you think in the comments,

Niklas Lohmann

Niklas Lohmann

Thanks for neat write up! Hard work to be truly inclusive Technology
Martin Lindeskog

Martin Lindeskog

How about Interlingua? I have tried to learn this language for some time… 🙃 I will reach out to some enthusiasts and teachers of this international auxiliary language.

Peter Nordmark

@Martin Lindeskog Klingon?
Martin Lindeskog

Martin Lindeskog (Edited)

@Peter Nordmark Interlingua is a real language with a great potential. It has a fascinating story and background history. Klingon is a fun language for “Trekkers”! 😎🖖
Terry Winship

Terry Winship

Such an interesting read and I can see how much time and effort and thought has taken taken place.
Do you want to read more like this? Hit subscribe. It’s FREE!

Never miss out on Developer Blog: Haaartland!

Community negotiated deals. Exclusive events. Posts. Polls and more. Free to members.