Implementing Internationalization (i18n) and Localization in React with react-intl
This article explains how to set up internationalization and localization in a React application using react-intl, covering project scaffolding, language file organization, ID naming conventions, message merging with webpack, and currency formatting with the Intl API.
When a web product expands to overseas markets, it must support multiple languages and adapt to local user habits; for front‑end developers this often means handling i18n (internationalization) and l10n (localization) efficiently.
Internationalization vs. Localization
Internationalization (i18n) is the process of designing software so that it can be adapted to different languages and regions without code changes, while localization (l10n) adds the region‑specific translations and formatting.
Technical Selection
Popular i18n libraries include i18next, vue‑i18n, react‑intl, angular‑translate, and i18n‑js. Because the project uses React, react-intl was chosen for its fast integration, Hook support, native Intl API compatibility (including IE11), server‑side rendering support, and strong community.
Basic Usage
Using create‑react‑app to scaffold the demo:
npx create-react-app i18n-demoInstall the library:
yarn add react-intlCreate an src/i18n folder with JSON files for each language (e.g., zh.json and en.json ) and define an ID hello with appropriate translations.
Modify App.js to provide the locale and messages via IntlProvider and add language‑switch buttons:
import
React, { useState }
from
'react'
;
import
{ IntlProvider, useIntl }
from
'react-intl'
;
import
'./App.css';
// language files
const
zhJson =
require
(
'./i18n/zh.json'
);
const
enJson =
require
(
'./i18n/en.json'
);
// Hi component
const
Hi = () => {
const
{ formatMessage: t } = useIntl();
return
(<>{t({ id: 'hello' })} React);
};
function
App() {
const
[locale, setLocale] = useState('zh');
const
messages = locale === 'zh' ? zhJson : enJson;
const
onSwitch = (lang) => () => setLocale(lang);
return
(
简体中文
English
);
}
export default
App;Naming Conventions
To avoid ID collisions when a project grows, IDs should be namespaced using the component path, e.g., comps.hi.hello . A helper getMessages function uses require.context to load all i18n/*.json files, prepend the namespace, and merge them:
const getMessages = (locale) => {
const msgJson = {};
const ctx = require.context('./', true, /i18n\/.*\.json$/);
ctx.keys().forEach((file) => {
const namespace = file.replace(/^\.\/(.*)\/i18n\/.*$/,'$1')
.split('/')
.map(str => str.toLowerCase())
.join('.');
const langKey = file.replace(/.*\/i18n\/(.*).json$/, '$1');
const langValue = ctx(file);
const newValue = {};
for (const key in langValue) {
newValue[`${namespace}.${key}`] = langValue[key];
}
msgJson[langKey] = { ...(msgJson[langKey] || {}), ...newValue };
});
return msgJson[locale];
};The Hi component then accesses the namespaced ID:
const Hi = () => {
const { formatMessage: t } = useIntl();
return (<>{t({ id: 'comps.hi.hello' })} React);
};Currency Formatting
Different regions require different currency symbols. react-intl provides formatNumber for this purpose:
formatNumber(1000, {
style: 'currency',
currency: 'CNY',
minimumFractionDigits: 0,
useGrouping: true
});The style option can be decimal , currency , or percent . The currency field expects an ISO currency code such as CNY , EUR , or GBP . Additional options include useGrouping and minimumFractionDigits .
Global formatting can be configured on IntlProvider via the formats prop:
function App() {
const [locale, setLocale] = useState('zh');
const [messages, setMessages] = useState({});
const formats = {
number: {
currency: {
style: 'currency',
currency: { zh: 'CNY', en: 'GBP' }[locale],
minimumFractionDigits: 0,
},
},
};
return (
{/* ... */}
);
}Conclusion
Effective internationalization requires choosing a flexible library, establishing clear ID naming and namespace rules, and configuring global formatting for dates, numbers, and currencies. Proper planning reduces future maintenance effort and ensures a smooth localization workflow as the project scales.
HomeTech
HomeTech tech sharing
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.