I am kind of new using i18next with React. I am currently working on building a personal website/portfolio with ReactJS/TS and want to translate content to English. I use JSON files to store my translations.
I’d like to keep things organised so I have several translation files in different folders:
- My
/public/locales/en
and/public/locales/fr
folders contain basic translations for my website (like buttons, page titles, text, etc.), - My
/src/data/en
and/src/data/fr
folders contain data that I want to display dynamically (projects, skills and career milestones).
So far, “basic” translations work perfectly fine. With the help of this article and this one, I have created a LocaleSelector
component that allows me to switch languages.
Things get trickier when it comes to dealing with repetitive data like those stored in my /data
folder, because I cannot seem to get my translation files loaded and rendered properly.
I’ll illustrate my issue with the projects.json
use case.
Before using i18next, it was pretty straightforward: I had 1 file that I imported into my Projects
component, used .map()
function to iterate and automatically render a ProjectElement
component for each object in my array.
Now, I get the following error: TypeError: projectsList.map is not a function
.
My projects.json
file is structured as follows:
[
{
"id": 1,
"title": "My project 1",
"isComplete": true,
"tasks": [
"task1",
"task2"
]
}
// rest of code
]
My i18n.ts
file is configured as follows:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import translationEN from '../public/locales/en/translation.json';
import milestonesEN from './data/en/milestones.json';
import projectsEN from './data/en/projects.json';
import skillsEN from './data/en/skills.json';
import translationFR from '../public/locales/fr/translation.json';
import milestonesFR from './data/fr/milestones.json';
import projectsFR from './data/fr/projects.json';
import skillsFR from './data/fr/skills.json';
const resources = {
en: {
translation: translationEN,
milestones: milestonesEN,
projects: projectsEN,
skills: skillsEN,
},
fr: {
translation: translationFR,
milestones: milestonesFR,
projects: projectsFR,
skills: skillsFR,
},
};
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources,
fallbackLng: 'en',
interpolation: {
escapeValue: false,
},
debug: true,
});
export default i18n;
And this is my Projects
component:
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import ProjectElement from './ProjectElement';
import { Switch } from '../ui/switch';
import { Label } from '../ui/label';
import type { ProjectInterface } from '@/@types/dataTypes';
function Projects() {
const { t } = useTranslation(['translation', 'projects']);
const projectsList: ProjectInterface[] = t('projects', {
returnObjects: true,
});
// console.log('projects list:', projectsList) >>> returns: 'projects';
return (
<main className="projects-container">
<div className="projects-title">
<h2 className="page-title">{t('projects.title')}</h2>
</div>
<div className="projects-content">
<div className="projects-list">
{projectsList.map((project) => {
return <ProjectElement key={project.id} project={project} />;
)}
</div>
</div>
</main>
);
}
export default Projects;
I was expecting my console.log
to return an array, but it simply returns a string (hence, the errorTypeError: projectsList.map is not a function
). The thing is, I tried to console.log
my projectsEN
data in the i18n.ts
file and it worked. I probably have made a mistake in configuring and loading my namespaces or i18n, but I really do not understand where.
I went through the official documentation and several other resources, they did not help.
Do you have any clue about this issue?
Many thanks in advance for your help!
NollieChtn6 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.