Software localization workflow

Learn best practices and recommendations on localization workflow.

Lokalise branching explained

Branching allows you to create separate versions of your translation project. Once enabled, you can create and manage multiple independent versions of your project. You can switch between these versions, delete them, and merge changes from one to another. For more information, check out the post on Lokalise branching.

It's crucial to understand that branching in Lokalise operates differently from commonly used version control tools such as Git. The key differences to keep in mind are:

  • There is no possibility to revert a branch merge.
  • There is no possibility to branch from a non-master branch.
  • Conflict resolution logic may differ; refer to the documentation for more information.
  • Branches in Lokalise are not automatically linked to or created in Git repositories and vice versa.
    There are certain limitations for branched projects:
    • Some actions and features may only be specific to a branch; refer to the documentation for more information.
    • Some actions and features are only available for the master branch, such as automations, custom processors, and snapshots; refer to the documentation for more information.
    • It's not possible to restrict user access to a specific branch. Team members will have access to all Lokalise branches.


Lokalise branching vs. Git branching

It's important to recognize that there may be differences in features and conflict resolution between Lokalise and Git branching. Lokalise branching was specifically designed for localization purposes.

Uses of Lokalise branching

Lokalise branching can be useful in the following scenarios:

  1. When you want to initiate localization at an early stage of the development process.
  2. When you want to preserve your production translations while still making new translation changes.
  3. When you want to compare and test two translation versions.

Before exploring these scenarios further, let's take a closer look at a typical development and localization workflow without using Lokalise branches.

Last-Step localization workflow (without Lokalise branching)

For developers working in a Git feature branch, the following flow is recommended when the localization team wants to start localization once the features are close to production. This is an example of a workflow in which there is no need to use the Lokalise branching feature.

  1. Once a feature's strings are ready for translation, they are committed to the Git branch connected to Lokalise through GitHub-like integrations, and Lokalise can retrieve the relevant resource files for translation.
  2. Lokalise will only have one version (master), as branching is not enabled.
  3. Localization managers can retrieve the latest changes from the translations-ready/staging branch in Git and let translators work continuously on translation updates.
  4. When the translations are finished, a pull request (PR) is made from Lokalise to the translations-ready branch in Git. The PR is reviewed, committed, and the entire branch is merged into the master branch in Git, creating a new release of the localized feature.
  5. Developers can use the Lokalise API or CLI to automate getting the latest translations for deployment or testing, eliminating the need to manually retrieve changes from Lokalise and create a PR in GitHub.
  6. For continuous development and localization, it is possible to create a PR with only translated, reviewed, or approved translations.

Development-stage localization

Consider a scenario where developers work on separate feature branches in GitHub and merge them directly into the main branch without first having a separate translations-ready branch to accumulate all changes. If a team wants to start localization while developers continue working on separate branches, before the feature is fully developed, alternative approaches can be taken, with or without the use of Lokalise's branching feature.

With Lokalise branching

Multiple branches in GitHub repositories can be connected with multiple branches in Lokalise, one branch per branch (e.g., main in GitHub connected to master branch in Lokalise).

It's important to remember that Lokalise branching is only for localization and not as advanced as branching in GitHub. The features and conflict resolution between the two will not be equal. It's crucial to establish the source of truth for branch merging, which is recommended to be GitHub.

There are two approaches to using Lokalise branching:

  1. Merging content in Lokalise (not recommended)
    This is not recommended as the GitHub flow of merging feature-specific branches cannot be replicated in Lokalise (unless you create a custom flow with Lokalise similar to what Lemonade outlines in their case study).

  2. Merging in GitHub
    Merging branches in GitHub gives better control over merge scenarios and expected behavior. It's also possible to reverse the branch merge in GitHub, while this is irreversible in Lokalise.

To avoid discrepancies between Lokalise and GitHub, it's best to rely on GitHub for conflict resolution during branch merging and to not merge in Lokalise. Here is possible workflow:

  • Enable branching in the Lokalise project
  • Create a branch in Lokalise for each GitHub feature branch with localizable content
  • Keep the master branch in Lokalise clean
  • For any content changes, create new branches in Lokalise and use them for translation tasks
  • Export content from Lokalise branches to GitHub branches
  • Merge branches into main in GitHub (rely on GitHub for conflict resolution)
  • Remove the feature branch in Lokalise after merging in GitHub is complete
  • Pull the new GitHub main to the Lokalise master, which may override changes in Lokalise

Note: The recommended approach is to keep the Lokalise master branch clean and make all changes in new branches to avoid losing any work in progress on the Lokalise master branch not present in GitHub.

Without Lokalise branching

You can achieve the same results by using tags to differentiate branch-specific content.

For instance, you can add a tag to a translation key to indicate the branch where it was first introduced. Additionally, you can add tags to indicate the status of the translation key, such as "work in progress," "released," or "obsolete."

For example, you can use tags to mark translation keys with their Git branch of origin and their progress through development processes. You can use tags like "feature-1," "work in progress," "production," and "obsolete."

When downloading content, such as creating PRs in GitHub, you have the option to include tags in or exclude tags from the download bundle. This gives you flexibility to filter for keys that match your desired scope. For instance, you can export all keys with a specific feature branch tag and a "reviewed" status. Or, you can export all keys (or keys with the tag "work in progress") for the download bundle that contains all the content needed for staging. This can be done through Lokalise's UI, API, or CLI.


Branching by using tags

For more information, read the "Branching by using tags and separate projects" that covers the topic.

Testing-stage localization

Another reason to use branches in Lokalise is to maintain two distinct versions of content that are separate from each other: one version is clean and has all the translations deployed to production, while the other version has changes that are being tested.

Managing different content versions (production and staging) can be achieved in various ways.

With Lokalise branching

The Lokalise branching feature has a suggested flow to keep the Lokalise master branch clean and synchronized with the released content in the Git main branch. The changes should be made in a "testing" branch in Lokalise, which can be synchronized with the customer's staging environment. Once the changes are approved, the "testing" branch is merged into the Lokalise master branch, replacing it with all changes.

Here is a possible workflow:

  • Enable branching in Lokalise
  • Keep the Lokalise master branch clean
  • Create a testing or staging branch in Lokalise
  • Translate amended content on the testing branch
  • Export the testing branch content from Lokalise to Git staging for testing
  • Merge the testing branch into the Lokalise master branch when all changes are accepted
  • Export the Lokalise master branch content to the Git main branch

This workflow minimizes conflicts from branch merges and creates a more predictable process by only making changes on the testing branch. However, note that a branch merge cannot be reverted in Lokalise. To revert a merge in Git, the same changes need to be manually made in the Lokalise master branch by uploading files to Lokalise and by manually overriding changes.

Swapping Lokalise branches:
Use Lokalise's master branch as a staging branch in GitHub for full utilization of Lokalise's features, such as automations, snapshots, and custom processors, which are only supported for the master branch. Create a separate non-master branch in Lokalise as a production branch in GitHub. The flow would be as follows:

  • Enable branching in Lokalise
  • Create a new branch named main
  • Use Lokalise's default branch (master) as a staging branch and synchronize it with the Git staging branch
  • Synchronize Lokalise's main branch (non-master) with the Git main branch
  • Make all changes on the Lokalise master branch (such as adding raw content and pre-translating with Automations), then export the same content for testing
  • After testing, merge the Lokalise master branch into the Lokalise main branch, and push the content from the Lokalise main branch to the Git main branch.

Without Lokalise branching

You can also achieve a similar workflow without using branches in Lokalise for cases where you only want to test changes in a staging environment before releasing them to production.

Tag-based approach + translation filters:
As previously mentioned, tags can be used to differentiate translation keys in different branches, as seen in this article.

It is possible to include or exclude translation keys in a GitHub PR, but it's also necessary to filter which translations should be included in the PR.

The example below illustrates how to filter and export translations using Lokalise:

A developer added a key with an English source copy "Hello world." Linguists translated it into Spanish as "Hola Mundo" and the stakeholders (e.g., copywriters, QA, legal) reviewed it and marked the translation as "reviewed."

Using Lokalise's UI, CLI, or API, you can filter the bundle during the download process using tags and translation statuses. If you export the content with filters such as "all" translations, "reviewed-only" translations, or "last reviewed" translations, the key and its Spanish translation "Hola Mundo" will be included in the pull request (PR).

If the source copy is changed to "Hello, my world" and the translation is changed to "Hola, mi mundo," this becomes the latest and current version, but the approvers have not marked it as "reviewed" yet.

To export the approved content (e.g., content for production), you can use the "last reviewed" filter on export. In this case, the "Hola Mundo" translation will be returned in the resource file because "Hola, mi mundo" has not been reviewed yet.

For testing, you can download a file from Lokalise with "all" translations, and Lokalise will take the most up-to-date translation version, which is "Hola, mi mundo". This resource file can be sent for testing on a staging environment.

You can also use Lokalise CLI and API endpoints to create pipelines that rely on different translation filters, e.g., "all" translations are downloaded and sent to "staging," and "last reviewed" translations are sent to the production environment.

Once "Hola, mi mundo" is marked as reviewed, it will be picked up by the "last reviewed" filter in future downloaded files.

Using a combination of tags, translation statuses, and export options, you can (for example):

  • Export keys tagged as "production" with "last-reviewed" strings to get the version closest to the master in GitHub
  • Export all keys and all translations to get the version closest to the staging in GitHub (with all recent changes)