Lingual

Checking your i18n on the CI

Introduction

It is always a good idea to run some checks against your codebase when opening up a pull-request or when merging a branch. We run different tests, builds and other checks before or after a merge. But how often have you ran any checks to validate if your translation files are in sync and in a valid state?

Using continuous integration to validate i18n specific files is useful. We want to run some validations and checks in regards to i18n, which most probably will include some JSON, YAML files or other formats, containing the locale specific translations. We will talk about the possible checks we might want to run and how they can fit into your existing workflow in this write-up.

What we want to validate

One way to run checks against an existing branch or after a merge is to run an action that should validate that all locale files are in sync. That action should also check if any translations are broken and try to detect if any keys are unused in the codebase, but exist in the default locale file.

The result of running the action should provide us with enough information about the current status of the validated translations. Typically translations can be out of sync without anyone noticing, especially if the translations are not handled by developers but by translators or managers, that are detached from the actual code.

We can use Lingual i18n-check , a tool for checking your translations, which can be run on the CLI as well as on the CI. i18n-check can help with validating translation files, checking for missing and/or invalid/broken translations. By comparing the defined source language with all target translation files it will try to detect all inconsistencies between source and target files. Next we will install i18n-check and setup a Github action that will run checks every time we open a pull request.

Setting up the Github Action

First thing we need to do is install i18n-check:

yarn add --dev @lingual/i18n-check

Via npm:

npm install --save-dev @lingual/i18n-check

Via pnpm:

pnpm add --save-dev @lingual/i18n-check

The next step is to update the package.json file and add a new command:

"scripts": {
// ...other commands,
"i18n-check": "i18n-check"
}

Once the script is updated, the i18n-check can be run via the command-line, i.e. via yarn i18n-check.

Now that we have i18n-check installed and the command set up, we can write a workflow definition using a YAML file:

name: i18n Check
on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

jobs:
  i18n-check:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@master

      - name: yarn install & build
        run: |
          yarn install
          yarn build          

      - name: yarn i18n-check
        run: |
          yarn i18n-check -t translations/messageExamples -s translations/messageExamples/en-us.json          

We can save the file as i18ncheck.yaml and add it to the .github/workflows folder, where your other actions are defined.

Interestingly there is not much else to do from a technical perspective, but it might be good to talk about the options that you can define when using i18n-check. Before we go into some of the details, you can consult the project’s README where you can find general information about setting up the workflow as well as the available options .

There are three important options that you can use depending on your use-case: format(-f, --format), target(-t, or --target) and source(-s, --source). By default i18n-check supports the icu message format, for example if you are using react-intl then you don’t need to provide the format option. Additionally there is support for i18Next, so if you are using react-i18next, then provide the format via -f i18next.

Depending on your folder structure, your target and source options can differ, you can check the examples section to see how you can work with different folder structures and tell i18n-check how to validate against these.

For simplicity reasons, we can take a look at the example workflow from above:

yarn i18n-check -t translations/messageExamples -s translations/messageExamples/en-us.json

The folder structure looks like the following:

- translations/messageExamples/
  - en-us.json
  - de-de.json
  - it-it.json

i18n-check will use the en-us.json file as the source and compare all other files in that folder against the source. This is a possible outcome when running the command on the CLI:

Example CLI output

i18n translations checker
Source file(s): messageExamples/en-us.json

Found missing keys!
┌──────────────────────────────┬────────────┐
│ file                         │ key        │
├──────────────────────────────┼────────────┤
│  messageExamples/de-de.json  │  richText  │
│  messageExamples/de-de.json  │  yo        │
│  messageExamples/de-de.json  │  nesting1  │
│  messageExamples/de-de.json  │  nesting2  │
│  messageExamples/de-de.json  │  nesting3  │
│  messageExamples/de-de.json  │  key1      │
└──────────────────────────────┴────────────┘



Found invalid keys!
┌──────────────────────────────┬─────────────────────┐
│ file                         │ key                 │
├──────────────────────────────┼─────────────────────┤
│  messageExamples/de-de.json  │  multipleVariables  │
└──────────────────────────────┴─────────────────────┘



Done in 0.02s.

We can get the same outcome when running it on the CI with the above workflow.

Example CI output

Summary

The example should have helped with better understanding how the CI can be used to ensure that your translations are valid. Especially translations files are hard to keep in sync, as they might be in constant change due to different input sources, f.e. translation management systems. Running them before or after a merge ensures that the checks are constantly ran and can inform when files are out of sync or translations are broken or unused.

If you have further questions in regards to setting up the workflow or more general questions in regards to running i18n validation on the CI or just general feedback on this post, you can find Lingual on Twitter .

We are working on a new translation management system with first-class branching and CLI integration.

Subscribe to our newsletter and we'll let you know when the beta becomes available.