Automated Localization
You have probably already heard of continuous localization. It's important as software development is a never-ending process, and with new features, you usually need to add new strings.
Fully automated localization is a level above it. As a developer, you only set up it once, and then, you can forget about it completely.
And as we are going to use Github Actions, it's gonna be fun!
Configure Localization Platform
Let's suppose that your mobile, desktop or web app is ready for localization, and strings in the source language are stored in JSON, YAML, iOS' strings, Flutter's ARB, or some other common format.
Sign up with Localazy, create a new project, install the CLI tool, and then create and test your localazy.json
configuration. You should be able to upload the source language files and download localized ones.
My configuration is as simple as:
{
"readKey": "read-key",
"writeKey": "write-key",
"upload": {
"type": "json",
"files": "locales/en.json"
},
"download": {
"files": "locales/${lang}.json"
}
}
From this moment on, Localazy is the place to manage your translations, translators, and contributors. And as a bonus, it translates your app to up to 80 languages for free by sharing translations with other apps.
Creating and testing localazy.json
is essential as it's used by the Github actions described below.
Setup Secrets
Private data should not be committed, and so, before the commit, let's remove the read and write keys from the configuration file above and instead place them to Github Secrets.
Create a repository on Github if you haven't yet, go to Settings > Secrets, and add keys here. My configuration looks like:
Ignore Localized Files
The source language file - in my case en.json
- is the source of truth, and for localized files, it's the latest version on Localazy. I don't need those files to be committed to my repository.
With a simple .gitignore
file placed in the locales
folder, I can filter out all localized files except for the source language one:
!en.json
*.json
Automate Uploading
If you are not familiar with Github Actions, I recommend reading more about it. It may take some time to get used to it, but it saves you a lot of time. We use it extensively for building releases of our Localazy CLI.
The configuration below is all I need for uploading the source language file en.json
to Localazy with each commit that changes it. I add a new feature, add new strings to en.json
, commit it, and push it. Done.
And all you need to do now is to create .github/workflows/upload.yml
file with this content:
name: Upload to Localazy
on:
push:
paths:
- 'locales/en.json'
jobs:
localazy-upload:
name: Upload strings to Localazy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: localazy/upload@v1
with:
read_key: ${{ secrets.LOCALAZY_READ_KEY }}
write_key: ${{ secrets.LOCALAZY_WRITE_KEY }}
If you need to fine-tune it, there is the documentation for the upload action on Github Marketplace.
It's also simple to configure the on
clause to upload strings to Localazy only for releases, certain tags or branches. See its configuration on Github docs.
On each push touching en.json
, I get this beauty:
Automate Downloading
Normally, you would integrate downloading localizable files from Localazy into your build chain, so they are added before building the release.
For clarity, let's test just the downloading and omit other steps.
Create file .github/workflows/download.yml
for downloading the latest version of localizable files whenever the tag v*
is pushed.
name: Download from Localazy
on:
push:
tags:
- 'v*'
jobs:
localazy-download-test:
name: Download strings from Localazy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: localazy/download@v1
with:
read_key: ${{ secrets.LOCALAZY_READ_KEY }}
write_key: ${{ secrets.LOCALAZY_WRITE_KEY }}
- run: |
# Test that localized files were downloaded by listing
# the content of locales folder.
ls locales/*.json
Of course, this example effectively does nothing as files are only downloaded to the action, and if we don't use them to produce the release build, they are lost once the action is finished and cleared.
The documentation for the localazy/download
action is available on Github Marketplace.
Pushing v2
tag to my test repository (notice that there is cs.json
file):
Source Code
The source code of a demonstrational project for this post is available on Github. Do not forget to explore the content of the .github/workflows
folder!
Closing Words
As you can see, it's simple enough to completely remove the localization burden from your shoulders with Localazy. No more file handling. All the translations of your lovely app can be managed in a single place with beautiful UI designed for developers and those that want them to bring their apps into the multilingual realm.
Top comments (5)
Sounds like a wonderful project and I'll definitely take a closer look. But I'm quite sure it doesn't entirely take the burden off your shoulders – unless you want the extra languages as a curiosity/gimmick instead of a way to build your user base.
Getting quality translations out of this still requires building up a trusted, multilingual community. You cannot simply re-use existing translations ("shared translations") blindly because the meanings can be completely wrong. The shorter the text, the easier it is to get wrong!
However, the support of different formats is impressive. I would use this as a translation management tool, which I understand is one of the ways it can also be used. 👍👍👍
Btw, if you set up Github Actions this way, you can still use the community around your apps to translate them.
This is just a way to upload/download localizable files but you can decide how you want to translate your apps.
I know exactly what you mean! You should take a closer look for sure ;-). Because Localazy is not only an automated tool. It's a complex translation management solution.
1) The shared translations are accurate for shorter texts :-). In fact, it doesn't work well for longer texts. And since we target mostly apps (mobile, web, and desktop), the shared translations feature is trained with this given field in mind. For short texts, it's way more accurate than Google Translate and similar services.
2) Of course, there are also machine translations available (Google and Amazon at the moment). They are better for longer texts.
3) Localazy never uses shared or machine translations without your approval! There is our unique review system, so you are always in control and can approve or reject translations.
4) We are soon going to introduce another awesome feature - the virtual contributor - translating using shared and machine translations in combination with a human touch/verification behind it on our side! It may not be the best translation way in all situations but it will be way cheaper than professional translations and good enough for starting with new languages.
5) Community around your app is the key! We invested extra effort into this part. You can invite users, contributors, volunteers, or external translators and they get a tool to translate your app, get the context that is important for quality translations, comment, suggest improvements, etc.
6) Even for the community, if you don't mark a given person as trusted, all translations go through our review, so you still retain full control over quality. This is awesome as you can spend 2 months developing new features and you are never going to be lost in what happened with translations.
Localazy exists because I, as a developer, struggled with localizing my mobile apps for years, so I know exactly all these pains you are talking about :-).
Thank you very much for your thorough response! What you've done so far and the plans you have sound exciting. I will be signing up for the tool and playing around with it for sure ("playing" since I don't have any real-life projects I could use it for).
I'm from the translation side in this and through the years the appreciation of professional translators seems to have diminished: "Google Translate is free, why do I have to pay money for translation." Or, "my nephew speaks English and took some French at school, he can do it!"
That's why it gets a bit under my skin, I admit 🙏, when translation is being reduced to just "press of a button" (I don't mean that that is what Localazy does). I love that there are projects like this that make translation easily manageable and – more importantly – accessible to more people, but on the other hand I don't want people thinking that absolutely anyone can translate and, consequently, that professional translators are redundant. Professional translators are experts and specialists in their own field, just like e.g. software developers in their own. 😊
Perhaps apps are simple enough a text type where something like this can work really well. A lot depends on what's "good enough" quality for your need: impeccable or getting somewhat understood – or something in the middle.
In closing, I'll have to admit that even though I'm not a professional translator, I got my 4 Hacktoberfest PRs from translations and am planning to contribute more translations to open source projects in the future. I trust my skills well enough to dare to do that.
I fully agree with you that high-quality localization needs more than just hitting the button.
I also fully agree that professional translators have their unique role and that they are irreplaceable. However, Localazy allows you to involve real users of your app/SW, and they, to some extent, may be an even better fit than professional translators as they have actual experience with the app, understand the context, etc.
However, when no users are willing to translate the app to their native language (and it's a typical case for some markets where localization is critical), professional translators are the way to go.
By the "good enough", I mean translation that is mostly accurate but may contain some issues. Such translation is usually an excellent motivation for users to come and help to improve it. Again, real users with real experience.
I will be glad if you try the service and let me know your comments, suggestions, and ideas. Feel free to get connected: linkedin.com/in/vaclavhodek/