Always make your apps localizable from the start

Any major software development framework has in-build localization mechanism. This will allow any app built with it to be able to easily change the language and other culture-specific settings depending on the users’ preferences.

You may think that this doesn’t apply to your app. Perhaps you never intend to release it outside of your own country. But you might be wrong.

I have already worked for two organizations that didn’t originally intend to sell a particular app outside of a particular country. But then the business started going well and the company has expanded its market. Suddenly, there was a requirement to make the UI available in different languages.

And I must say, retrofitting localization functionality in an app that wasn’t localizable to begin with is a painful process. This is exactly why you should design your apps in such a way that they are localizable from the start.

Why bother with localization?

Even if you are completely sure that you will never sell your app outside your country, you should still design it in such a way that it’s easily localizable. It’s just a good habit to get into. Treat it as a good practice, like SOLID principles and design patterns.

Also, localizable application design is easy. All major frameworks already provide simple ways of achieving it. For example, ASP.NET Core documentation explains the entire mechanism on a single page that will take you around an hour to go through. The one for CakePHP is even shorter. So, the overhead of implementing a localization mechanism in your app is very small. At most, it will just add a total of a couple of hours to the process of app development.

On the other hand, if the situation changes in the future and your app will now have to be localizable, retrofitting the localization mechanism into it will be a long and tedious process. You will probably have to go through your entire codebase to determine which bits of text are meant to be user-readable, and which ones need to only go into logs. For example, if your entire tech support team is in the US and a user in Italy is in trouble, you don’t want all the log entries generated by the user’s session to be in Italian.

You will also have to do the same for culture and timezone settings. After all, different cultures use different display formats for numeric values and dates. For example, while people in the US put the month number before the day number in a date, almost everyone else does it the other way around. Likewise, some countries use the comma (,) as the decimal point, while others use the dot (.).

If you are dealing with a mature app, you will probably have a lot of code to manually go through. You will probably also have to deal with different code formats. For example, some of the user-readable text would be in the HTLM, some will be in JavaScript, and the rest will be generated somewhere in the backend. This is why the process of retrofitting localization into a codebase will take weeks if not months.

And, as I said previously, such situations are not entirely unheard of. This is why it’s better to spend one or two extra hours on something that you may not need than sacrifice a huge chunk of your productive time when you will definitely need it.

The main principles of localizable design

There are several techniques that you need to implement to make your app localizable. They vary depending on the framework you use. But there are three principles that are universally applicable:

  • No raw human-readable text anywhere in the code
  • No hardcoded culture settings
  • All dates and timestamps are stored in UTC

Let’s go through them one by one.

No raw human-readable text anywhere in the code

The exact implementation of the translation mechanism will vary from framework to framework. In some of them, like most of the PHP ones, you will have a direct translation from your main language to other languages. In other frameworks, like ASP.NET, Xamarin, and Flutter, you will have arbitrary keys that will map to actual textual values in language-specific dictionary files.

But regardless of how the translation mechanism is implemented in the framework of your choice, the principle is the same. You should never put any raw text directly into your code. Instead, you should apply the translation function that uses a dictionary key as its parameter.

If you never need the translations, you will end up with only one dictionary file with the values in your main language. Or, if you are using a framework that uses direct translations, you won’t even have that. But in any case, any human-readable text should be inside the framework-specific translation function. Any code that has raw text in it should fail the code review.

No hardcoded culture settings

Culture settings, among other things, consist of things like date formats and what characters act as decimal point separators. They are very important, because the same character may mean different things in different cultures. For example, while a comma character is there in some cultures to make large numbers more readable, it’s a decimal separator in others.

If you hard-code these settings, especially in the backend, then there may be a problem. For example, the number 1,245 will be understood as twelve hundred and forty-five in the UK, while it will be understood as one with three decimal points in Eastern Europe. Likewise, 08/12/2020 will be understood as the twelfth of August in the US and the eighth of December in Germany.

This is why you must always store numeric and date values in a raw culture-independent format. You will only need to apply culture settings when you are ready to display this data to the user. To do so, you apply the culture settings from the user’s browser or device.

All dates and times are stored in UTC

Coordinated Universal Time (UTC) is a timezone-independent. It refers to the time on the Greenwich meridian without adjustments for daylight savings.

This is the standard way of storing date and time values before applying any timezone-specific offset to them. This is why it’s also way easier to convert UTC to any other timezone than it is to convert them between time zones.

Yes, the users will want to see the dates and timestamps in the timezone that they are in. But it’s only important when they actually see it. So all you need to do is apply the relevant timezone once this data actually reaches the presentation layer (the UI) of your application.

Most of the inbuilt timezone conversion functionality available in most of the programming languages already assumes that the input date was provided in UTC. So implementing this will be easy.

Another added benefit of this is that, when you store all your dates in UTC everywhere in your backend, different parts of your application will not have to do any additional timezone conversion.

Wrapping up

If you don’t work for a business with an international scope, you have probably not even considered the importance of making your apps localizable. Now you know why it’s important. You can also see how easy it is to implement.

Remember, an ounce of prevention is worth a pound of cure. Or a gram of prevention is worth a kilo of cure if you are in continental Europe. It’s way easier to make your app localizable while never needing this functionality, than retrofitting localization into it when you definitely need it.

Of course, we haven’t covered how to apply localization an any specific framework. This is up to you to learn. But every major framework will have a mechanism to do it. And the documentation should be easy enough to find.

Happy hacking!