Internationalization for Everyone

Here at Sprout, we have a diverse and multilingual user base. Needless to say, if we do not translate our text for different locales, our users would not be able to become fully engaged with our wellness platform. To suit the needs of the company, the internationalization (abbreviated i18n) tool needs to fit a certain criteria.


1. Work with Existing Tech Stack

Since Sprout uses CodeIgniter and Angular. We need a way to support i18n for both platforms.


To start off, CodeIgniter has a built in tool supporting localization with their Language class. For those unfamiliar, CodeIgniter uses an associative array to store key value pairs for translations, as shown below:

$lang = [];
$lang['error_email_missing'] = 'You must submit an email address';
$lang['error_url_missing'] = 'You must submit a URL';
$lang['error_username_missing'] = 'You must submit a username';


Angular doesn’t have i18n capabilities out of the box, but the angular-translate team has created an easy to use module that allows us to define translations as seen below:

.config(($translateProvider) => {

$translateProvider.translations(‘en’, {
greeting: ‘Hello’,
   $translateProvider.translations(‘fr’, {
greeting: ‘bonjour’,

Take Aways

Both CodeIgniter and Angular use a key-value pair, so our solution must consist of a key-value pair that can be mapped to these two respective format, PHP associative array and JSON respectively.

2. Familiar Interface for Non-Developers

Delegating the i18n of an application to developers may be a great idea if your developers are fluent in the languages that needs to be localized, but most of the time that won’t be possible.


The storage of these translations and their keys should be accessible to others. Otherwise, the developers would have to input the keys which could otherwise be done by another worker, or even a translator. As an example, asking a person to insert translations one row at a time is very tedious and time consuming and not to mention, ludicrous. Which leads me to the next point, usability.


The interface with which the users will interact should be easy and familiar. There should not be much training (or none at all!) required for people to familiarize themselves with the process.

A solution…

Use Google Sheets!

Google Sheets allows us to easily create translations as each column can correspond to a language!

For example:

| en_CA     |  fr_CA     | es_ES   | ja_JP    |
| --------- |------------| ------- | —------- |
| Hello! | bonjour! | ¡Hola! | こんにちは |
| Good bye! | au revoir! | ¡adiós! | さようなら |

There is a slight problem with the current solution, we are still missing the key for these values. However, there is an easy fix, add identifier column(s) or keys to each row in order to identify them. Using the earlier example, we’ll have:

| key      | en_CA     |  fr_CA     | es_ES   | ja_JP    |
| -------- | --------- |------------| ------- | —------- |
| greeting | Hello! | bonjour! | ¡Hola! | こんにちは |
| goodbye | Good bye! | au revoir! | ¡adiós! | さようなら |

What if wanted to sort them by features or pages? Add another key!

| category    | sub-category | en_CA     |  fr_CA     | es_ES   |
| ----------- | ------------ | --------- |------------| ------- |
| formalities | greeting | Hello! | bonjour! | ¡Hola! |
| formalities | goodbye | Good bye! | au revoir! | ¡adiós! |

We can also break a single sheet into multiple sheets when we deem that there are too many translations to keep track of in sheet.

What we accomplish:

  • Spreadsheets are commonly used and are easy to learn
  • All translations are in one place
  • Translations can be easily searched and sorted

What’s left:

All we have to do is generate the i18n files to be used by the code. In my case, CodeIgniter and Angular.

Due to the nature of the process, I’ve created a npm module in order to speed up the process of generating the i18n files, google-sheet-i18n. Feel free to flag an issue or suggest any features you would like to see on Github.