CodePark/ questions / i18n in React & Next.js
START PRACTICINGPRACTICE
Frontend question · Internationalization › i18n in React & Next.js

Your app supports 20 languages and the translation files are 2 MB in total. How do you load translations without hurting performance?

const loaders = {
  en: () => import("./locales/en.json"),
  ar: () => import("./locales/ar.json"),
  fr: () => import("./locales/fr.json"),
};

export async function loadMessages(locale) {
  const mod = await (loaders[locale] ?? loaders.en)();
  return mod.default;
}

Load only the current user's language, and only the part the current page needs.

Split per locale. Never bundle all 20 languages into the main JavaScript file. Each user needs one. Load the current one with dynamic import(), as in the code. The bundler creates one chunk per language. Or fetch JSON files from a CDN.

Split per feature. Group messages by page or feature, for example common, checkout, settings. i18next calls these namespaces. A user who never opens settings never downloads its strings.

Avoid a flash of untranslated text:

  • With server rendering, load the messages on the server and include them in the page, so the first paint is already translated.
  • In a client-only app, wait for the messages before rendering, or preload the file with <link rel="preload">.
  • With React Server Components, most strings stay on the server and never reach the client bundle.

Cache well. Put a content hash in each file name, like ar.3f9a1c.json, and serve it with a long Cache-Control max age.

Keep formatting data small. Use the built-in Intl APIs instead of shipping locale data for dates and numbers. Load polyfills only for browsers that need them.

  • Load only the current locale's messages, with dynamic import() or a fetch.
  • Split messages by feature or page, called namespaces in i18next.
  • With server rendering, include the needed messages in the page to avoid untranslated text.
  • Server Components keep most strings out of the client bundle.
  • Hashed file names allow long-term caching.
  • Use the built-in Intl APIs instead of shipping locale data.