9 biggest localization issues developers face and how to solve them

Implementing a proper localization workflow can be a rather complex task, especially when you have never done it before. There are definitely many things to consider and keep in mind. In this article, we will discuss some of the most common localization issues that we, as developers, face and how to solve them with the help of Lokalise TMS (translation management system).

The concepts presented in this article were also discussed during one of our webinars. The recording is available on YouTube:

1. Synchronizing translations between TMS and code repository

This task is probably the most common one for developers. We need to make sure that translation files are synchronized properly between the translation management system and the code repository hosted on platforms like GitHub or Bitbucket. But how do we achieve this? Do we export the translations from code repo to TMS manually? Should we create pull requests every time translators perform updates? You can’t expect translators to perform these tasks themselves. Perhaps they aren’t the most tech-savvy people, or they don’t have experience in tasks outside their usual role, after all. However, doing this manually on your own is quite a tedious and error-prone process. Is there any way to alleviate this localization issue? The answer is yes!

Lokalise provides integrations with popular code hosting services: GitHub, Bitbucket, and GitLab. By employing them, you can easily import and export translations with just a couple of clicks. As an example, let’s see how to setup and work with GitHub — the two other integrations work in the same way.

Setting up GitHub integration

To get started, open Lokalise and navigate to a project for which you’d like to set up integration. Click the “More” button, proceed to Integrations, find GitHub, and press Connect. Next, you’ll need to generate and copy/paste a personal access token from GitHub. To achieve this, navigate to github.com, click on your avatar in the top right corner, and choose Settings > Developer settings > Personal access token. Then click “Generate new token”, as below:

Make sure to choose repo scope for the new token, and then click “Generate token”.

 

Copy the generated token (remember that you won’t be able to do so after closing this tab).

Finally, return to Lokalise and paste your token into the Personal access token text field. Next, you can choose the Repository and Branch to pull from.

When you are ready, click “Select files to pull”. Make sure to only choose your translation files!

Using GitHub integration

Exporting translations from GitHub

After completing the setup process, you may now export translations from GitHub to the Lokalise project. To do this, simply click “Pull now”.

It might be also a good idea to set up a webhook to automate pulling the changes to Lokalise as you push to GitHub. For this, open GitHub, navigate to your repository settings and proceed to Webhooks. Copy/paste the “Auto-pull URL” provided in the Lokalise integration configuration (see the above screenshot). You will need to provide the Auto-pull secret generated on the integration page as well.

Importing translations to GitHub

After translations have been updated on Lokalise, you will need to synchronize them with GitHub. To do this, proceed to the Download page on Lokalise and adjust the download options as needed by choosing file format, languages, plural format, etc. Make sure to enable GitHub in the Triggers section and then click Build and download or Build only.

By pressing the latter button, the corresponding pull request will be created on GitHub, but the translations archive won’t be downloaded to your PC. It is also a good idea to use the Preview button first, so you can see the resulting file/folder structure before triggering the creation of the pull request.

After you start the build, the following process will happen:

  1. A new branch is created from the last revision of the branch you chose in the integration setup. The branch name will look like this:  lokalise-2018-03-12_15-14-13.
  2. A commit with all the chosen files is created in the new branch.
  3. A pull request from the new branch to the previously chosen branch is created.

Then you may navigate to GitHub and merge the new pull request as usual. Piece of cake!

2. Automatically downloading new translations and monitoring for changes

The next localization issue faced by developers is the need to automatically download translation files to your application on a regular basis. Apart from that, some developers may need to monitor changes in their Lokalise project: for example, to check which translations were added or updated. To overcome these issues, Lokalise provides two powerful tools: API and webhooks. Let’s start by discussing the API.

Lokalise API

As you probably know, API means “application programming interface”. It allows third-party applications to communicate with the given service and manage it by sending properly formed HTTP requests. Lokalise provides a feature-rich API that enables you to perform all major tasks, including file import and export, translation updates, contributor management, project creation, and many more. There are client libraries for major programming languages such as PHP, Go, JavaScript, Ruby, and Python.

To get started with the API, you’ll need to generate a special token under your Lokalise profile (API tokens section).

Remember that the token owner must have the proper permissions to perform the required tasks: for instance, you cannot add contributors if you are not a project admin.

After generating the token, you may send API requests. The code will vary greatly based on the programming language and your end goal, but I’m going to show you a small example written in Ruby. It illustrates how to download translation files from the given project.

Example: downloading translations

require 'ruby-lokalise-api'
require 'open-uri'
require 'zip'
require 'yaml'

client = Lokalise.client 'your_token_here' # 1
opts = { # 2
  format: 'yaml',
  placeholder_format: :icu,
  yaml_include_root: true,
  original_filenames: true,
  directory_prefix: '',
  indentation: '2sp'
}

uri = client.download_files('your_project_id', opts)['bundle_url'] # 3

Zip::File.open_buffer(URI.open(uri)) do |zip| # 4
  zip.each do |entry|
    next unless /\.ya?ml/.match?(entry.name) # 5

    filename = entry.name.include?('/') ? entry.name.split('/')[1] : entry.name # 6
    data = YAML.safe_load entry.get_input_stream.read # 7
    File.open("locales/#{filename}", 'w+:UTF-8') do |f| # 8
      f.write(data.to_yaml) # 9
    end
  end
end

So, this program works in the following way:

  1. We create an API client using the ruby-lokalise-api gem. Then:
  2. Generate a new hash with download options.
  3. Download the files and extract the bundle_url from the response. This URL points to the ZIP archive with your translation files.
  4. Unzip the archive and process its contents.
  5. Check the filename and make sure it has a .yaml or .yml extension.
  6. The filename may contain slashes meaning that the file is stored under a subdirectory. In this case take only the filename, without the subdirectory part.
  7. Read the file contents and process it as YAML.
  8. Create or open an existing file under the locales directory. The filename was already generated in step #6.
  9. Save translations to the file.

You can run the above script on a regular basis to download new translations to your application.

Webhooks

A webhook is a mechanism that sends an HTTP request to the specified URL once a given action has taken place. With the help of Lokalise webhooks, you may notify your application about certain events.

To add a new webhook, open your Lokalise project, click the “More” button and proceed to Integrations. Find “Webhook” and click “Connect”. Next, enter the Webhook URL to which you want to send notifications. Take a note of the X-Secret header which can be used in your application to make sure that the request comes from a trusted source. Finally, choose one or more events to send notifications about.

Now, when a chosen event takes place the corresponding notification in the form of an HTTP POST request will be automatically sent to the provided URL. Here is an example of a “translation updated” notification:

{ 
  'event' => 'project.translation.updated',
  'translation' => { 'id' => 406_293_058, 'value' => 'Everything about us', 'previous_value' => 'About us' },
  'language' => { 'id' => 640, 'iso' => 'en', 'name' => 'English' },
  'key' => { 'id' => 56_711_483, 'name' => 'menu::about',
    'filenames' => { 'ios' => nil, 'android' => nil, 'web' => '%LANG_ISO%.json', 'other' => nil } },
  'project' => { 'id' => '4578f32954cb9.016', 'name' => 'My Project' },
  'user' => { 'full_name' => 'John Doe', 'email' => 'john@doe.com' },
  'created_at' => '2020-09-28 16:17:38', 'created_at_timestamp' => 1_601_302_658
}

Also note that you can send a notification using webhooks when exporting translation files. For this, simply navigate to the Download page, enable the ‘Export webhooks’ option and provide your webhook URL:

In this case, the notification will contain a path to the ZIP archive with your translations.

3. Downloading translations with proper formats and structures

Translation file formats will vary widely depending on the technology you are using. For instance, Ruby on Rails uses the YAML format, and Angular apps require XLIFF files, whereas Android employs XML. We need an easy way to download translations in different formats for different platforms. Luckily, Lokalise provides a simple solution to this issue.

Assigning keys to platforms and files

First of all, you can assign translation keys to one or more platforms, namely Web, Android, iOS, and Other. This way, you can control which keys to download for specific formats. For example, if a key is assigned to Web and iOS platforms, it will be exported when choosing JSON and Apple XLIFF formats. However, it won’t become a part of the bundle when choosing Android XML.

You can assign translation keys to separate files. Moreover, if the key belongs to multiple platforms, file names can be customized separately. Using this feature, you may control which key should be placed into which file during export.

Download options

Upon opening the Download page, you will be presented with numerous options to customize the export.

In-depth explanations for each option can be found in the documentation, but let’s discuss the most important ones:

  • Format. Here you may choose one of the file formats to use. These formats are separated by platform (Web, Android, iOS, Other). Therefore, if a key only has Web platform selected, it won’t be exported for Android (though you may export all keys regardless of their platform).
  • File structure. Pick how your translations are organized: place all translations in a single file per language or utilize previously assigned filenames. Here you may also provide directory prefixes which is convenient when translation files for different languages should be placed into different folders.
  • Filter by filename. Export only the keys that were assigned to the specified files.
  • Plural and placeholder format. Select the format that should be provided for your technology. The choices will vary based on the chosen format.
  • Data to export. Decide what keys to download. For example, you may omit all untranslated strings or download only the strings that were verified.
  • Languages. Choose one or more languages to download translations for.

Then, after setting up the options, click one of the buttons at the bottom of the screen:

  • Build and download. Download a ZIP archive with all the chosen translations to your PC. This will also trigger export webhooks and any other integrations chosen in the options (e.g., GitHub).
  • Build only. Trigger all export webhooks and chosen integrations. The archive won’t be downloaded to your PC.
  • Preview. Clicking this button allows you to preview the directory structure and contents of your translation files right in the browser. The archive won’t be downloaded, and nothing will be triggered.

4. Finding duplicate translations

When a team of developers works on the same project, they may end up producing duplicated translations. For example, you create a new page with a license agreement and add an “OK” button there. Next, you have to create a translation key named “license_ok” with an “Ok” value. However, your fellow developer may also introduce another translation key, “accept”, with the same “Ok” value. It means that this value has to be translated twice which is not ideal. Moreover, you may have multiple translation files for different platforms that have the same translation values but different key names. This may result in a total mess really quickly. But do not worry, Lokalise is here to save the day once again!

Use duplicate finder to deal with similar translations:

After opening the Duplicate finder, you will see all duplicated translations. Using the top menu controls, you can adjust the language and choose the platforms:

There are two ways of dealing with duplicates: linking and merging. Therefore, let’s discuss these approaches separately.

Linking keys

Linking keys means establishing a reference between two entries. One entry will serve as a parent and the other one will become a child. Whenever the parent translation is modified, the child will be modified as well. You may also create multiple children for the same parent. When these translations are exported, all child keys are provided with the proper values from the parent.

For example, here are two duplicate iOS translations:

If you press “Link all to selected”, the chosen key “ok” will become parent, while the “agree” key becomes the child. Return to the project editor:

The “Ok” translation for the “agree” key is now highlighted in green meaning that it references another key. The reference is established by providing the following translation value: [%key_id:123%], where 123 is the parent key ID. To break the link, simply remove this construct.

Merging keys

Merging keys means creating a single entry from multiple translation keys. Following the example above, I’ve enabled the Per-platform key names option in the project settings and returned to the Duplicate finder:

Now you can choose one of the keys and merge all other entries to it. In the screenshot above, the merge target is the “ok” key. The “ok_continue” will be removed and merged to it. As long as I’ve enabled the Per-platform key names, the “ok_continue” key name will be preserved for the Android platform. Note however, that a single key cannot have different translations and therefore merging may not always be the best solution.

After clicking “Merge to single entry”, let’s return to the editor:

The established link is still present, and the two duplicated entries were merged into one. Moreover, the key names were preserved for each platform! When you download your translations again, all three keys will be exported with the proper translations. This means that even though we have taken care of the duplicates, the corresponding keys have not gone anywhere and will still be exported. This is quite important because your code already relies on those keys and you probably don’t want to just remove them. Still, it is actually possible to completely remove duplicates on the Duplicate finder page by clicking on the trash bin icon.

5. Allowing translation teams to work on different features in parallel

We as developers love version control systems like Git. They allow us to have a base version of the project and work on new features in other branches without affecting the master. Also, we can have different developers working on separate features in parallel, which is crucial for larger teams. Can this approach be applied to a TMS? But of course! In Lokalise you can create as many branches inside the project as needed and switch between them in just two clicks.

So, to get started, open your project, click “More” and proceed to Settings. Here, in the Miscellaneous section, enable the Branching option and click “Save”. The master branch of the project will be created automatically. You can add more branches by clicking the dropdown:

To manage branches, choose Branches from the dropdown. Here you can rename, delete, and create branches. Note that the master branch cannot be renamed or deleted.

To merge the branch, click “Merge into” and choose the destination. If any conflicts are detected, you’ll have to resolve them before merging. Either resolve all conflicts in one go using either target or destination or take care of them one by one.

To view the conflicts, click the “Show” button.

Note that some aspects of your project are global for all branches. These are settings, contributors, comments, glossary, history, and screenshots.

6. Working with placeholders

Universal placeholders

Another common localization issue is the proper usage of placeholders. As you probably know, placeholders allow you to insert dynamic values right into the translations. The thing is, different formats require different placeholders. If you are using the same translations for multiple platforms, that may become an issue as you’ll have to adapt your placeholders somehow. But, with Lokalise this not a problem at all because you can take advantage of universal placeholders.

Suppose you are uploading a YAML translation file as below:

en:
  welcome: "Hello, %{username}"

Such files are used in Ruby on Rails applications. However, if you also need to export this translation for Android, the %{username} placeholder should be replaced with %1$s. Of course, you don’t want to make this change manually, right? Therefore, before importing your initial translation file, enable the Convert placeholders option.

When this option is checked, all your platform-specific placeholders will be converted to universal ones. For example, %{username} becomes %1$s:username. Yet, the real magic happens when you download your translations again for the specific platforms. During export the universal placeholders will be replaced with the platform-specific ones automatically! This means that the same translations can be utilized on multiple platforms without any more worrying about the placeholders.

In the export options, you can always choose how to format placeholders (these options will vary depending on the chosen file format):

Showing placeholders as blocks

Unfortunately, sometimes translators might mess with your placeholders. They might remove part of it by mistake or even try to translate it. Therefore, we need an easy way to show that the placeholder is a special construct and should not be modified in any way. Lokalise allows you to display placeholders as blocks in the graphical editor. When this option is checked, all placeholders will be displayed in the following way:

Even if this option is not enabled, placeholders will still have a special highlighting, for instance:

7. Working with plural keys

Placeholders are not the only thing that is platform-specific: unfortunately, plural keys have very different formatting rules as well. Moreover, different languages have different plural forms. For example, in English there are two plural forms, whereas in Russian there are four. You can’t possibly know all these specifics, and there’s no need to do so, as Lokalise is here to assist you. Our service automatically exports plural keys in the proper formats, and has built-in support for virtually any language on Earth, including their plural forms.

To make a key plural, open its settings and toggle “Plural” to On:

The plural forms will be provided automatically for each added project language:

If you need to change the default plural forms, click on the language flag in the top menu and choose Language settings:

Next, enable the “Custom plural forms” option and choose as many forms as you need:

During export, you can choose the plural format to apply (these options will vary depending on the chosen file format):

8. Previewing translations in the design stage

This localization issue affects both developers and designers. You need to make sure that translations for different languages fit properly within your design. This is very important because certain phrases in some languages may become significantly longer or shorter, thus breaking the layout. Lokalise provides Adobe XD and Figma integrations to overcome this problem. These integrations work in the same way, so I will briefly show you how to get started with Figma.

First of all, open your Figma project and install the Lokalise plugin from Menu > Plugins > Manage plugins. Next, open Menu > Plugins > Lokalise. Connect your Lokalise account and choose the translation project from the dropdown (it is possible to create a new one as well).

Choose the text elements to push to Lokalise or simply click “Push all”.

The chosen texts will be exported to Lokalise. If the text is already present in the Lokalise project, it won’t be duplicated by default. Rather, the existing key will be linked to the Figma text element (but this behavior can be further customized). Moreover, for each key, a separate screenshot will be displayed showing where exactly the text is located. This is very convenient and allows you to provide your translators with context.

After the keys are exported and translated, you may preview the localized design in Figma. To achieve this, simply choose a different language from the dropdown (see the screenshot above). Your texts will be translated almost instantly!

9. Providing context for translators

The last localization issue that I would like to tackle today is providing context to your translators. You’re probably aware of that old joke: “Are you really a translator? Say something in your language then!” – “Well, I need a context for that…”. It might sound funny, but in reality translators do require context in order to deliver quality results. They need to understand the specifics of your app, where and how the given texts are utilized, what their purpose and functions are, and so on. Therefore, Lokalise has three main features that allow you to add more information about your translation keys.

Comments

The simplest way of giving some general context is by using key comments. To add a comment for any key, click on the “Comments” button just below its name, as below:

After pressing this button, you will see a simple text box where you can add any comments as needed. For example, to explain where this translation key will be displayed, whether the translation should be formal or informal, etc.

Screenshots

As the old saying goes: a picture is worth a thousand words. Therefore, showing how and where exactly the text is to be displayed is very convenient. Lokalise enables you to upload screenshots and link them to translation keys. Moreover, you can enable automatic key detection: this feature will try to recognize text on the uploaded image and link these portions of text to existing keys.

To get started, open your project and navigate to the Screenshots page. Next, click “Select a file” (optionally, enable “Try to find keys on images” to enable automatic detection). Once the image is uploaded, you may edit its settings and link portions of it to specific keys. This can be done by simply drawing an area on the image and choosing a key from the dropdown:

After the keys have been linked to the screenshot, the corresponding images will appear under each key. The chosen area will be highlighted on the image, showing where exactly the text is located, for instance:

To learn more check out the screenshots documentation and the screenshots workflow guide.

LiveJS: web in-context editor

Lokalise also provides you with a web in-context editor that allows for editing of translations directly on the webpage. Here is a brief demonstration:

Getting started with the LiveJS editor is easy. First of all, include LiveJS script in your page:

<script>
    window.LOKALISE_CONFIG = {
      projectId: "18302045592fa799a35d20.15846093",
      locale: "en"
    };
    (function () {
      var a = document.createElement("script");a.type = "text/javascript";a.async = !0;
      a.src = ["https://app.lokalise.com/live-js/script.min.js?", (new Date).getTime()].join("");
      document.body.appendChild(a)
    })();
</script>

Next, expose key names in the HTML, because the editor must understand what text element corresponds to what key. This is achieved by adding data-lokalise and data-key attributes:

<span data-lokalise data-key="index.hero.title">Translation platform for developers</span>

And that’s it! Now when opening the webpage, you’ll see the in-context editor and will be able to use it to perform translations. After hitting “Save”, all the changes will be forwarded to the specified Lokalise project.

Conclusion

So, in this article we have discussed some common localization issues faced by developers, and also have seen how to fix them. Hopefully, by now you are feeling more confident about implementing localization workflows in your projects! I thank you for stopping by today, and until the next time.

Related posts

Sign up to our newsletter

Get the latest articles on all things localization and translation management delivered straight to your inbox.

Read also
Localization made easy. Why wait?
The preferred localization tool of 1500+ leading global companies