/react-localization

A little demo on localization using format-js v5 (React-intl), create-react-app and flat.

Primary LanguageJavaScript

A little demo on react-localization with Create-react-app/ format-js v5(React-intl)/ flat, with a more readable and maintainable structure.

Using Create-react-app, format-js v5 (React-intl) and flat for localization.

Main focus: Demostrate keys under each language folder could be declared in object structure instead of key-value mapping.

Run project

Run npm start to view the demo

Demo

Demo image

Highlights

Flatten the keys instead of hard-coding in each language folder

Standard way in React-intl:

const messagesInEnglish = {
  "student.name": "Name - {name}"
  "student.contact.phone": "Phone - {phone}"
};
  
const messagesInZhTw = {
  "student.name": "姓名 - {name}"
  "student.contact.phone": "電話 - {phone}"
}; 

const messages = {
  en: messagesInEnglish,
  "zh-Hant-TW": messagesInZhTw
};

But in fact we can (also prefer to) define the keys and values in each of the language folder (src/i18n) with object type, which will be more readable.

// src/i18n/en
export const student = {
  name: "Name - {name}",
  contact: {
    phone: "Phone: {phone}",
  },
};

// src/i18n/zh_tw
export const student = {
  name: "姓名 - {name}",
  contact: {
    phone: "電話: {phone}",
  },
};

Using flat, we can flatten the keys in language object automatically, and convert into a correct format for react-intl

import flatten from "flat";

const messages = {
  en: flatten(en),
  "zh-Hant-TW": flatten(zh_tw),
};

Supporting array in locale file

By using flat, we can also setting our locale keys/ values in array format

export const student = {
  projects: [
    {
      name: "student.projects.0.name",
      desc: "student.projects.0.desc",
    },
    {
      name: "student.projects.1.name",
      desc: "student.projects.1.desc",
    },
  ],
};

// i18n/en/student.js
export const student = {
  projects: [
    {
      name: "Camera",
      desc: "Photo",
    },
    {
      name: "Foods",
      desc: "Apple",
    },
  ],
};

// i18n/zh_tw/student.js
export const student = {
  projects: [
    {
      name: "拍攝",
      desc: "照片",
    },
    {
      name: "食物",
      desc: "蘋果",
    },
  ],
};
{localizationKeys.student.projects.map((p, idx) => {
  return (
    <ul>
      <li>
        <span>
          {intl.formatMessage({
            id: localizationKeys.student.projects[idx].name,
          })}
        </span>
        {` (${intl.formatMessage({
          id: localizationKeys.student.projects[idx].desc,
        })})`}
      </li>
    </ul>
  );
})}

array_locale

Centralizing the place for retrieving locale keys

We can centralize the locale keys to avoid the typo.

locale keys centralized image

Setting default language

Merging the current locale with English, we can display English as default instead of text's id in UI, when the text id is failed to look from locale file

const [locale, setLocale] = useState(navigator.language);
const [mergedMessages, setMergedMessages] = useState(messages["en"]);

useEffect(() => {
  // Merging English and current locale, avoid showing Text id if cannot look for the translate in locale file
  setMergedMessages(Object.assign({}, messages["en"], messages[locale]));
}, [locale]);