Search code examples
reactjstypescriptwebpackcode-splitting

Is there a way to "dynamically" load json files into my component based on a condition?


Let's say I have a couple translation files like so:

import English from "./lang/compiled-en.json";
import Spanish from "./lang/compiled-es.json";

and so on for all the languages we plan to support. These are imported directly into the component they are used, and our app as a whole is split into chunks with webpack that may contain many components and thus, many strings.
It would be ideal to only be importing the languages.json file I need depending on the user's locale, and not import all of them while having to check the locale and using only one.
I tried a super naive stab at it here, but it certainly does it work:
Helper function existing in another directory:

export async function loadLocaleData(locale: string, path: string ) {
  switch (locale) {
    case "en-US":
      return await import(path + "/lang/en-compiled.json");
    case "pt-BR":
      return await import(path + "/lang/pt-br-compiled.json");
    default:
      return await import(path + "/lang/en-compiled/en.json");
  }
}

I was thinking that importing this helper function into my components that need translations would look in their own directory for the translation file. But even when I have that path hardcoded to specify exactly where the translation file is, I still get errors.
The above may be implemented into a component like so:

  const localeContext = useContext(LocaleContext);

  const messages = loadLocaleData(
    localeContext.locale,
    "packages/components/Preferences/Billing"
  );

And then I'd ideally pass just that message into my IntlProvider that wraps this individual component.

This definitely isn't working. Is there a way to make it work? I know what I want to do, I'm just not sure how possible it is.


Solution

  • You can use dynamic imports like you are trying, but you need to use absolute paths. Otherwise your bundler (Webpack) won't actually know where to find them.

    Alternatively, store your language files in your public/ directory and use the public path to it. Webpack won't touch those files (besides index.html) and might be your best option here.