Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create React App CRA2 with react-intl i18n message extraction and translation

i18n Translations

To generate new translations:

  1. remove .messages folder
  2. Extract all messages into .messages dir with: yarn i18n:extract
  3. Add new messages into {lang}.json files with: yarn i18n:manageTranslations
  4. Translate any new entries in {lang}.json files and commit to repo (see Untranslated keys: output of previous command for list of keys needing translation)

Setup

yarn add react-intl
yarn add react-intl.macro
yarn add --dev react-intl-translations-manager

Notes

This gist shows how to use react-intl with defaultMessage of English so a separate default en.json file is not needed, while not ejecting from Create React App.

ignore the extracted i18n messages by adding /.messages to .gitignore

(gist filenames cannot have / in filename, so these files use - in place of directories)

{
"name": "jeffsheets-react-intl",
"dependencies": {
"react": "^16.8.1",
"react-dom": "^16.8.1",
"react-intl": "^2.8.0",
"react-intl.macro": "^0.3.6",
"react-scripts": "2.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --colors",
"i18n:extract": "MESSAGE_DIR='./.messages' react-scripts build",
"i18n:manageTranslations": "node ./translationRunner.js"
},
"devDependencies": {
"react-intl-translations-manager": "^5.0.3"
}
}
import React from 'react';
import { FormattedMessage } from 'react-intl.macro';
export const App = ({username}) => {
return (
<>
<h1><FormattedMessage id="app.title" defaultMessage="Sample App" /></h1>
<FormattedMessage
id="app.hello.user"
defaultMessage="Hello {username}! Welcome!"
values={{username}}
/>
</>
);
}
import es from './translations/es.json';
// English is the default message in each of our source files, so no need for a separate en.json file
const en = {};
// If we add more than just spanish, just import the files and export it below: export default { en, es, de }
export default { en, es };
{
"app.title": "Aplicación de ejemplo",
"app.hello.user": "Hola {username} ¡Bienvenido!"
}
import React from 'react';
import ReactDOM from 'react-dom';
import { App } from './components/App';
import { addLocaleData, IntlProvider } from 'react-intl';
import enLocaleData from 'react-intl/locale-data/en';
import esLocaleData from 'react-intl/locale-data/es';
import translations from 'i18n/locales';
//English and Spanish (add more langs here)
addLocaleData(enLocaleData);
addLocaleData(esLocaleData);
//In future this would be set by a control on the page
// if you want to test Spanish just change this to es
const localeProp = 'en';
ReactDOM.render(
<IntlProvider
locale={localeProp}
defaultLocale="en"
key={localeProp}
messages={translations[localeProp]}
>
<App username="test123"/>
</IntlProvider>,
document.getElementById('root')
);
// See https://github.com/GertjanReynaert/react-intl-translations-manager
const manageTranslations = require('react-intl-translations-manager').default;
manageTranslations({
messagesDirectory: '.messages',
translationsDirectory: 'src/i18n/translations/',
// en is defaultLocale so no need to list en here
languages: ['es']
});
@arvinsim

This comment has been minimized.

Copy link

@arvinsim arvinsim commented Apr 17, 2019

yarn install ... should be yarn add ...

@Bluzkry

This comment has been minimized.

Copy link

@Bluzkry Bluzkry commented Dec 30, 2019

Shouldn't src-index.js, line 7 be the below?

import translations from '.i18n/locales'; not import translations from 'i18n/locales';

@jeffsheets

This comment has been minimized.

Copy link
Owner Author

@jeffsheets jeffsheets commented Dec 30, 2019

@arvinsim, yes good catch!

@Bluzkry, depends on if absolute resolutions are setup or not, but yes that would work too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.