How to use code splitting with JSON files in React application
Code-splitting for resources
Code-splitting is a built-in function in many code bundlers like Webpack. It's used mostly to lazy load only required JavaScript code or other resources. It helps in improving application performance by loading only required parts of the application, instead of fetching all resources at once. This is a perfect solution for localization purposes to load translations for only one language instead of all of them to speed up your web application.
Medium-sized web application with about 1000 unique translation keys can contain about 50kb translated messages for one language. If you would support 10 languages in your app, whole translation file could have size nearly 1 megabyte.
Learn more about code-splitting in React.
How to lazy load JSON file in React?
Here is the asynchronous function TypeScript, which accepts languageKey
as a string
and returns a loaded JSON file as an JavaScript object.
const loadJson = (languageKey: string): Promise<any> => {
return new Promise((res, rej) => {
import(`../assets/i18n/${languageKey}-messages.json`).then((data) => {
res(data?.default);
});
});
};
How to use lazy load in React app?
Here is the full example code for lazy loading translations from local JSON files. The code is written in TypeScript,however, it should be easy to convert into plain JavaScript.
import {useState} from "react";
const [locale, setLocale] = useState('en-US');
const [messages, setMessages] = useState({});
// first useEffect
useEffect(() => {
const locale = window.navigator.language;
setLocale(locale);
}, []);
// second useEffect
useEffect(() => {
loadJsonAsync = async () => {
const messages = await loadJson(locale);
setMessages(messages);
}
loadJsonAsync();
}, [locale])
// use your messages
React will invoke:
-
the first
useEffect
hook only once on every page re-render. We are getting the language from web browser. Learn more about navigator.language object. -
the second
useEffect
hook whenlocale
value is changed to lazy load different JSON file with translations.
You cannot invoke async functions in
useEffect
React hook, that is why we create a newloadJsonAsync
function.
Check example how to load translations from backend using a standard fetch API.
Use loaded JSON messages with IntlProvider
To use loaded JSON messages with FormatJS, you can simply pass locale
variable and messages
object as props
to IntlProvider.
<IntlProvider
locale={locale}
messages={messages}
>
{children}
</IntlProvider>
children
variable should contain your React component or even a whole application (e.g., <App/>
) in which you want to provide translations.