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