Guide: How to prepare your application for i18n & l10n

Localazy's objective is to make your life easier and hassle free by automating the localization process of translating your app.

🤔 Why internationalize my software?

Diversifying and expanding your software internationally is undoubtedly something that will add a lot of value to your product/service and bring more security to your business.

⚔️ International Competition: Instead of limiting yourself to your domestic market, you will be competing with markets from all over the globe 🌍.

💸 Higher profits: When you throw yourself into the global market, you will be expanding your product/service across borders, allowing more visibility. This, just by itself, can result in higher profits as you’ll be able to win customers from other regions.

🔀 Differentiation: Differentiating can be an option that will bring a great advantage; since the international market may require specific changes to the products/services to adapt to them better.

![](upload://3U7KRRUJnkGQnkfhMu34SV92fgO.png)

❓ How to internationalize my software?

To develop multilingual software, we are required to go through three phases: i18n,l10n and finally, t9n.

Internationalization is popularly known in the development and technological world as i18n,. It is the process of creating or transforming products or services so that they can effortlessly be adapted to specific local languages and cultures. While Localization, commonly known as l10n, is the process of adapting an internationalized product to a particular region or language. Finally, t9n stands for translation.

If the project is still to be planned

When the project planning hasn’t yet begun, design decisions are more manageable. Depending on the framework or library you are planning to use, you will be able to discover suitable i18n libraries and begin incorporating them from the start.

Be sure to choose one and carefully follow the steps on how to configure it during the early stages of development. One of the most popular is the i18next library as it is simple to use, and supports frameworks like React, Angular, Vue, Vanilla JavaScript and NodeJS.

If you want to know more about the i18n process, how to use a library like i18next or how it works on an empty project, check out our JavaScript app localization with i18next and Localazy article.

If the project is in production

In case of a project with large amounts of code and which is already in production and with customers using it for a fairly long time , things may become very complicated. Intrusive changes like adding i18n and l10n support to the application will not be easily feasible.

Nevertheless, if we use libraries like React or frameworks like Angular and ASP.NET Core, our situation will be better. It is recommended to gradually release the application or regional updates so that only a certain percentage of users will be affected in case of any issues.

For example, you can first publish a project with an instance of translatable messages to handle the default locale. For users, they will not feel any difference, but you will take the first step. You can then add each version incrementally to allow time to adapt.

Ideally, you should remember to also implement a way to add new translations without redeploying the application so that you can fix any errors without interruption.

Legal Reflections

When publishing apps in other markets, you need to ensure that your application complies with local laws and regulations. If it does, you may have to change some parts or aspects of it to adapt to different markets. For example, gambling apps are modified for different markets and areas in terms of payment systems, in-game currency, and randomized gaming elements to comply with the gambling laws of each market.

You also need to remember that legal issues may emerge depending upon how your application is really being utilized and not by how you designed it in the first place. This may imply that you will not have the option to deliver your application to specific nations. For instance, betting is illicit in nations like Korea and Taiwan. So releasing a betting game there would be illicit, regardless of how diligently you attempt to change it.

Data usage is also important to keep in mind as different countries have different laws in terms of data storage, sharing, security, and more. The difference between these laws and regulations lies in the need to obtain permission for user data, what data can be obtained and how to use it, including personal information (such as name, email address, social security number, etc.) and any user activity or behaviour. This applies especially for countries in the EU where GDPR (General Data Protection Regulation) applies.

Keeping content separated

The most important thing that you need to do regarding the project internationalization is separating the content from the code.

In order to create different versions of the content and different product flavours, nothing that the user will see in the application can be static. The version will be dynamically loaded and adjusted according to each locale.

You need to collect the content and store it in a repository so that you can easily create different versions of that content for any new locales you might want to add and load it into your project without influencing the code. This will allow the development teams to develop multilingual applications, while translators or team members responsible for the localization process can work separately, making it easier for both sides to work simultaneously.

The content is:

  • Media(image, video, sound) 📷
  • Text 📜
  • Date Format ⌛
  • Numbers 🔢
  • Currency 💰

Externalizing Strings

Text is without a doubt the most common way to communicate with the user of an app and so we will cover the importance of strings. First off, not all text needs to be external, only the one that the user will see. There is a lot of text that will always stay within the app itself for programming purposes, therefore it doesn’t need to be extracted or externalized. Text should also use UTF-8 encoding as it is capable of encoding all 1,112,064 valid character code points in Unicode, giving you the ability of supporting languages with different alphabets.

Externalizing the strings the users will see from the get-go, is a crucial step of i18n as it will save you huge amounts of time and a headache opposed to simply hardcoding all the project’s strings inside the project itself.

With all of that said, you need to write all the strings that are relevant to translation and each one of them will have a key assigned for location identification. All of them will be written in an external source, e.g. a text file. Or in case of the previously mentioned i18next library, you will use a JSON file.

If your project is organized by a framework, this file should be created inside a locale, lang or similar folder, and named by the default language you will use, if your project’s source language is English, then the filename will be en.json.

If you’ve started the project without externalizing the strings, there are a few options to help with the hassle, one of them being the GNU gettext.

gettext is a library that was built to minimize the i18n and l10n work. It works by extracting the strings directly from the source files and generating a template file with the strings that are going to be translated. It’s simple but flexible to use and it has plural support.

It is available for various languages (Python, C, PHP, Ruby, JavaScript and many more) and most frameworks already have it with some support. You can check it here.

If you choose this route, you’ll be in luck because Localazy supports gettext.

Alternatives to gettext are:

Translating the Strings

Use Localazy or find Translators

Having the default language file is a big step and taking in all the topics we covered so far is a challenge by itself, but the real legwork is to translate all the strings. Sure, if you have a project with a few dozens of strings, you might not be too bothered to translate it yourself or pay translators to translate them all. The real problem is when we have massive projects with hundreds, if not thousands of strings to translate. It will soon become messy, costly and painful to manage.

The good news is that Localazy allows you to go through the l10n process in a much more affordable, smoother and hassle free way.

Localazy is a developer-focused localization management platform that supports a wide variety of frameworks and an even more comprehensive range of formats through its CLI.

Localazy’s best features Hire the Virtual Translator for Continuous translation

Managing the external Strings

If you choose to do this process manually or if you have it automatically, in the mentioned languages folder you will have to have files with different naming (names that will depend on the language we will have translated inside the file) and with the same string keys as the original.

Example of en.json:


{
  "hello_world": "Hello World!",
  "like_ice_cream": "I like ice cream";,
  "bread": "Bread"
}

Different language file, for example, Polish in pl.json:


{
  "hello_world": "Witaj świecie!",
  "like_ice_cream": "Lubię lody";,
  "bread": "Chleb"
}

The file extensions used here are just for demonstration purposes as they can be different, depending on the programming language or framework used.

🏆 Challenges of i18n and Final Considerations

Plurals and String Interpolation

When we use numbers in the text, we tend to think there are only two cases, whether it is singular or plural. Still, different languages ​​have different numbering systems and different plural forms. Some languages ​​have singular, double, and plural nouns, while others have more specific rules about few or many nouns, and even the definitions of “rarely” and "many’’ are different. Since this is a common problem, most systems today support localization plural forms between different languages. Depending on the languages you want to add, you can check Unicode’s Language Plural Rules.

If we need to use variables inside the strings, we can use string interpolation as it allows us to insert variables directly into a string without concatenating multiple strings together.

This allows translators to view the complete sentence and modify it as needed, thereby changing the order of any strings or variables accordingly. To do this, we can use placeholders to define the variables. The variables can also change the plural forms. As an example of placeholder usage we will demonstrate a placeholder in PHP’s Laravel framework:


<?php
return [
  'voted'=>"The city most voted by the users is :city",
  'name'=>"My name is :name",
  'carStatus'=>"There is :carNum car blocking the road | There are :carNum cars blocking the road"
]
 ?>

The same file with the translated strings to Portuguese:


<?php
return [
  'voted_city'=>"A cidade mais votada pelos utilizadores foi :city",
  'name'=>"O meu nome é :nome"
  'carStatus'=>"Há :carNum carro a bloquear a estrada | Há :carNum carros a bloquear a estrada"
]
 ?>

Using the prefix :, we are then able to assign the variables: city and name. With the | character we are able to distinguish between singular and plural.

This example is simply for demonstration purposes as placeholders and plurals differ depending on which language/framework/library you are working with. Plurals can be an extreme challenge if we are translating a language with many forms, but Localazy supports all CLDR plural rules internally and generates them correctly for all languages defined there.

In some areas we want to internationalize our product to, we might need to implement Right-to-Left languages support.

You can check some examples of plurals and string interpolation on our How to build a multilingual PHP app with Localazy and Laravel article.

How to attract more contributors to translate your app?

✔️ Closing Words

As we could see by now, developing multilingual applications is not that easy as there is quite a lot to consider, plan and develop.

After all we’ve covered, it is recommended to plan a project to be internationalized right from the beginning and depending on the product flavours and versions we want to add, we might need to expand the external content besides just the strings for the text. Many of the concepts we talked about here and given examples have different methods of implementation, depending on the language/framework/library we are using, it is wise to read their documentation to avoid compatibility issues. The i18n path is not an easy one to take but at least you can count on Localazy to make part of it effortless.


This is a companion discussion topic for the original entry at https://localazy.com/blog/guide-preparing-application-for-i18n-l10n-localazy