DEV Community

Cover image for How to Translate Your Next.js App in 5 Minutes With Crowdin
Žan Horvat for zerodays

Posted on

How to Translate Your Next.js App in 5 Minutes With Crowdin

For the majority of websites using content management systems such as Webflow or WordPress, localization is not an issue, as it can be relatively easily done through the system.

But for custom solutions, such as custom web applications using Next.js or just plain React, this can be quite a pain.

When the client wants to have the product in another language, one of the developers has to open the code and manually translate the strings, as the process is often too technical to be outsourced and fully done by the translators.

Now, imagine having to translate the entire web app into more than one language - simply a buttload of manual work developers don’t have time for.

We decided to see if there are any solutions to this issue on the market, did a bit of research, and decided to try out Crowdin - and we think it’s awesome! It offers:

  • Support for almost all languages
  • Integration with 600+ apps (including GitHub integration)
  • Easy to use UI for translating strings

So for our needs we developed a localization pipeline around Crowdin and wanted to share it with you.

Localization pipeline

In our applications, translatable strings are stored in specific translation files (usually in JSON format). In addition to storing translatable strings in translation files, we usually use some sort of internationalization framework (for example next-i18next for our Next.js applications).

Example of our folder structure:

/project-root 
  /public 
    /locales 
      /en-INTL 
        common.json
      /sl-SI 
        common.json
Enter fullscreen mode Exit fullscreen mode

Example translation file common.json:

{
  "welcome_message": "Welcome to our app!", 
  "login_button": "Login", 
  "logout_button": "Logout"
}
Enter fullscreen mode Exit fullscreen mode

To keep the translation files updated, we use Crowdin CLI to upload the source files and download translations.

Once the strings are available in Crowdin, our clients or dedicated translators work on translating the strings into the target languages within the Crowdin web platform.

After translations are completed, Crowdin's integration with GitHub automates the next step. Crowdin automatically generates a pull request in the project's GitHub repository.

Code example

In this section, we’ll take a look at a step-by-step guide on how to implement the pipeline from the previous section.

  1. Create account and project on Crowdin website
  2. Download Crowdin CLI. If you use macOS, you can easily use Homebrew:
brew install crowdin@4
Enter fullscreen mode Exit fullscreen mode

Configuration file

After installation, you need to configure the CLI to work with your Crowdin project.

You can do this by creating a configuration file (crowdin.yml) in your project's root directory. Configuration file can be created with following command:

crowdin init
Enter fullscreen mode Exit fullscreen mode

After creating the configuration file, set Crowdin credentials. You can find them in the Crowdin Web UI.

'project_id_env': 'CROWDIN_PROJECT_ID'
'api_token_env': 'CROWDIN_PERSONAL_TOKEN'
'base_path_env': 'CROWDIN_BASE_PATH'
'base_url_env': 'CROWDIN_BASE_URL'
Enter fullscreen mode Exit fullscreen mode

The preserve_hierarchy property should be set to true. This ensures that the directory structure of the source files is maintained in Crowdin.

The files section in the configuration file specifies which files should be synchronized with Crowdin. It includes the paths to the source files and their corresponding locations for translated files. If your source language is en-US and translation files are located in /public/locales/<locale>/, the files section should look like this:

- source: '/public/locales/en-US/*.json'
  translation: '/public/locales/%locale%/%original_file_name%'
  dest: '/%original_file_name%'
Enter fullscreen mode Exit fullscreen mode

Let's explain this:

  • source specifies the pattern for files to be uploaded for translation.

  • translation specifies where the translated files should be placed locally. %locale% is a placeholder for the target language code.

  • dest indicates file name of translations.

Uploading/downloading translations from Crowdin

To streamline the process of managing translation files with Crowdin, two custom commands are used: push-i18n and pull-i18n.

We’ll define these commands in the project's package.json file and automate the process of uploading and downloading translation files.

"push-i18n": "crowdin upload sources && crowdin upload translations"
Enter fullscreen mode Exit fullscreen mode

The push-i18n command is responsible for pushing both source files and any existing translations to Crowdin. This command is typically run when you want to update Crowdin with the latest version of your project’s localization files.

"pull-i18n": "crowdin download sources && crowdin download"
Enter fullscreen mode Exit fullscreen mode

The pull-i18n command handles the process of downloading files from Crowdin to your local project. This ensures that you have the most recent translations available in your project.

To use these commands conveniently add them to the scripts section of your package.json file.

To upload your newly updated strings just use push-i18n. To update your local strings with changes from other translators just run pull-i18n.

Conclusion

Crowdin offers a great solution for a painful problem of web app localization. Instead of keeping the work on the developer side, the entire translation process can be done by non-technical team members, through an intuitive dashboard. Numerous integrations and language support are also a plus!

Do you recommend any other localization tools? Let us know in the comments!

This blog and its underlying research were made by the awesome team at zerodays.dev.

Top comments (1)

Collapse
 
best_codes profile image
Best Codes

Nice post! :)

I used Crowdin to translate my app here:
crowdin.com/project/codequill

It was certainly a great experience!