I have another approach to resolve your problem. (Though it might not be the best solution and it is not exactly using your en/ german translate, but i think they are similar)
First we can define a file with all localization keys:
// i18n/keys.js export const student = { projects: [ { name: "student.projects.0.name", desc: "student.projects.0.desc", }, { name: "student.projects.1.name", desc: "student.projects.1.desc", }, ], }; export const localizationKeys = { student: student, };
In i18n locale files, we can define the translations as below:
// 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: "蘋果", }, ], };
Export the translations in i18n to locale modules for react-i18n
// i18n/en/index.js import { student } from "./student"; const en = { general: general, }; export default en; // i18n/zh_tw/index.js import { student } from "./student"; const zh_tw = { student: student, }; export default zh_tw;
In your react components, you can access your localization Keys (keys.js) to get back each of the i18n keys name.
import React from "react"; import { useIntl } from "react-intl"; import { localizationKeys } from "./i18n/keys"; import { IntlProvider } from "react-intl"; import zh_tw from "./i18n/zh_tw"; import flatten from "flat"; import en from "./i18n/en"; const messages = { en: flatten(en), "zh-Hant-TW": flatten(zh_tw), }; export default function ProjectShowcase() => { const intl = useIntl(); 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 // In this case, it will always show EN translate as default if the text-id not found in a "zh_tw" locale setMergedMessages(Object.assign({}, messages["en"], messages[locale])); }, [locale]); return ( <IntlProvider messages={mergedMessages} locale={locale} key={locale} defaultLocale="en" > {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> ); }) } </IntlProvider> ) }
I have developed a little example on the react-intl, you may find more completed code inside: https://github.com/applelok/react-localization
IntlProviderbased on the user's browser languageresolveJsonModuleset to true in yourtsconfig.json