Unleash the hidden superpowers of react-intl (Part 2)

Jan Mühlemann
4 min readSep 23, 2018

--

Part 2: Get your react.js application using react-intl ready for localization

In the first part, you learned how to use babel macros to improve your markup.

You will find the first part of this series here: https://medium.com/@jamuhl/unleash-the-hidden-superpowers-of-react-intl-part-1-d6f99a32ef84

In this part after adopting all the features of the demo project you will be able to:

  • split translations into multiple files
  • using an in-context editor
  • loading translations from CDN
  • detecting the user language
  • automatically add new missing strings to your translation project
  • updating changed strings in reference language
  • submitting the description to translation context
  • setting last used information so you can safely remove keys not used any longer

From internationalization to localization

While the first part focused on helping developers writing nicer jsx markup we now will focus on helping your translators by making their work easier. One of the most important things in our fast-paced times is implementing a fast feedback loop, which is also recommended by all the common “Agile” methodologies.

So let’s go a step further:

From internationalization to continuous localization

We like to innovate the localization process by breaking the old slow loop of exporting extracted translations, passing them to translators and importing them back again. This old process does not fit into a modern development environment using continuous development and agile methods.

What we want: New content in your application should be immediately available in your translation management tool for your translators and newly finished translations should be passed down to the application without a developer needing to add a file to the repository or accepting a PR from the translation management.

Connecting your application to your translation management

In this sample we will use https://locize.com as our translation management tool — as it exposes all the needed functionality to bring localization to the level of continuous localization.

There is the locizer script available to connect your application with the translation project: https://github.com/locize/locizer

With it you can load translation files, save or update translation segments.

Step 1: We need a way to extend react-intl components during development

This should be rather easy:

import { FormattedMessage as FM } from 'react-intl';// find out if our react app runs in dev mode
const IS_DEV = !process.env.NODE_ENV || process.env.NODE_ENV === 'development';
// export a extended replacer component while development and original while in production
export const FormattedMessage = IS_DEV ? supportLocize()(FM) : FM;

Now let’s learn what the supportLocize() is:

Step 2: Let the component send new content to the translation service

In our code we have FormattedMessages like in regular react-intl projects but we consume our overridden component during development:

// see ./locize/index.js in development mode the
// react-intl components are extended to provide
// features like save of new ids, ...
// in production you get the regular unextended
// react-intl components
import { FormattedMessage } from 'locize';
<FormattedMessage
id="app.title"
defaultMessage="Welcome to {what} combined with locize"
description="Welcome header on app main page"
values={{ what: 'react-intl' }}
/>

Our extended component will take those props and create new translation segments on locize using the id and defaultMessage

Based on the defaultMessage already exists in the translations catalog or not, or the defaultMessage has changed we use the locizer functions to create or update the translation segment in the source language.

Awesome, now every time we add a new FormattedMessage or change a defaultMessage those values get added or changed in your translation project immediately.

Step 3: Directly load translations

By overriding the IntlProvider we could use the locizer script to directly load the translations that get published to the localization CDN provided by locize.

What the component basically does is taking a prop namespace to load the translation file and the needed intl locale-data:

// load the given file form locize
// and detect language while doing so
locizer.load(namespace, (err, messages, locale) => {
currentLocale = locale;
translations[locale] = messages;
// load react intl locale data
import('react-intl/locale-data/' + locale)
.then(localeData => {
addLocaleData(localeData);
// update state to render children
this.setState({
locale,
messages
});
});
});
}

The full code is very simple you can find the demo repository here: https://github.com/locize/locize-react-intl-example/blob/master/src/locize/index.js#L32

So this not only enables us to load one translation catalog, but by using that IntlProvider we could load multiple files and making translation a lot easier by splitting them into multiple smaller files.

Step 4: Enable translations inside the context of your application

There is “one more thing” (I mean, one more script) you can consume from locize which enables you to integrate the translation editor into your application. This way translators are able to click any content on your website and can directly translate it in the context of your application.

The integration of the locize editor is very simple:

locizeEditor.init({
lng: locale,
defaultNS: DEFAULTNAMESPACE,
referenceLng: REFERENCELANGUAGE,
projectId: PROJECTID,
private: PRIVATE
});

Now you can open your website appending the querystring param ?locize=true and you will see the in-context editor.

Summary

You see internationalization is done rather easily and localization hasn’t to be harder. With the right tools you can not only keep your development — translation cycle short but you can also improve the quality, save time and money.

You can find the full sample here: https://github.com/locize/locize-react-intl-example

Take the chance and try it yourself locize.com comes with a 14 day free trial.

--

--

Jan Mühlemann

Always in search for the holy grail ;)...loving javascript, node.js, html5, interaction design, usability