Skip to content
React실무 경험

Optimizing Build Size for React i18n Translations, Part 1

2 min readWorkMoved from my Tistory blogRead the Korean original

🌍 Optimizing React i18n in a real project

While developing the Autowini service, I had adopted react-i18next for multilingual (i18n) support.
At first I built it by importing the translation JSON files, but as the project grew, I ran into larger chunk files and slower initial loading.

Visualization of the per-language bundle sizes that caused the problem
Figure 1. Visualization of the per-language bundle sizes that caused the problem

So I changed how languages are handled altogether and applied i18n bundle optimization. Here is how I did it.

📌 The old way: bundling languages with import

At first, I imported the translation JSON files and put them directly into resources, like this.

js
import ko from './locales/ko/translation.json';
import en from './locales/en/translation.json';

i18n.init({
  resources: {
    ko: { translation: ko },
    en: { translation: en },
  },
  lng: 'ko',
  fallbackLng: 'en',
});

The advantages of this approach:

  • Simple structure, quick to set up
  • All translations are bundled with the app, so loading is fast

But the drawbacks were clear too:

  • As the number of languages grows and the JSON files get bigger, the JS bundle size grows sharply
  • In the end, this leads to longer build times and slower initial loading

🔧 The improvement: static files + HttpBackend loading

So I changed the structure as follows:

  1. Move the translation JSON files out to /public/locales/{{lng}}/translation.json
  2. Use i18next-http-backend so only the current language is loaded over the network at runtime
  3. Remove unneeded translation files from the JS chunks → smaller build size
js
import i18n from 'i18next';
import HttpBackend from 'i18next-http-backend';
import { initReactI18next } from 'react-i18next';

i18n
  .use(HttpBackend)
  .use(initReactI18next)
  .init({
    backend: {
      loadPath: '/locales/{{lng}}/translation.json',
    },
    lng: userLanguage,
    fallbackLng: 'en',
    interpolation: { escapeValue: false },
  });

🧠 What exactly is HttpBackend?

i18next-http-backend is an i18n backend plugin that lets you load translation resources asynchronously through HTTP requests.
In other words, instead of importing the translation JSON files and including them when the app first loads, the browser fetches only the files needed for that language over the network.

Example: a request to /locales/ar/translation.json → the translations come back as a JSON response

📉 Why does this help optimize the build?

The bundler I use is Vite, which uses Rollup internally.
Rollup combines every imported file into a single bundle (JS chunk), so if you import JSON, all of it ends up inside the JS.

But resources in the /public folder are only copied as static files and are not included in the bundle, which gave the following results.

  • Smaller JS chunks
  • Shorter build times
  • Faster initial loading

Build size results & thoughts

Before
Figure 2. Before
After
Figure 3. After

With the old structure, where every translation file was imported into the bundle, I often saw warning messages whenever I ran vite build. I'm glad this optimization took at least a little of that burden off.

As the project grows and the translation data increases, I'm sure this approach will prove even more effective.

  • #Autowini
  • #i18n
  • #React
  • #i18n build size optimization

More in Work