개요
프로젝트에서 다국어를 지원하는 방법을 찾아보다가 i18next 라는 다국어 지원 라이브러리가 있다는 것을 알게 되었습니다. 간단하게 사용하는 법을 기록하고 최종적으로 투두리스트에도 적용해 볼 예정입니다.
설치 및 실행
npm install react-i18next i18next
i18next는 다국어 지원을 위한 JavaScript 라이브러리이며, react-i18next는 i18next를 리액트에서 사용하기 위한 라이브러리입니다. npm install 명령어를 통해 설치합니다.
폴더구조는 다음과 같이 설정했습니다.
기본 세팅을 위한 i18n.js 먼저 살펴보겠습니다.
// i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import en from './en/translation.json';
import ko from './ko/translation.json';
const resources = {
en: {
translation: en,
},
ko: {
translation: ko,
},
};
i18n.use(initReactI18next).init({
resources,
lng: 'ko',
fallbackLng: 'en',
interpolation: {
escapeValue: false,
},
});
export default i18n;
resources 객체는 다국어 번역 리소스를 정의하는 역할을 합니다. 저의 경우 영어와 한국어에 대한 json 파일을 따로 정의해서 사용했습니다.
또한 i18n 객체에 initReactI18next를 사용하여 i18n을 초기화했습니다. 각 역할에 대해 간략히 설명하면 다음과 같습니다
- resources : 앞서 정의한 번역 리소스 객체를 사용하는 것입니다.
- lng : 기본 언어를 설정하는 것입니다. 위에서는 'ko'로 설정했기에 애플리케이션이 처음 실행될 때 한국어를 기본 언어로 사용하게 됩니다.
- fallbackLng : 설정된 언어(lng)에서 번역을 찾을 수 없는 경우, 기본 언어로 사용할 언어를 지정합니다.
- interpolation : {escapeValue : false} : 보안상의 이유로, 사용자 입력 값을 출력할 때 XSS 공격을 방지하기 위해 escape 처리가 필요하지만 리액트에서는 기본적으로 보호되므로 false로 설정합니다.
resources 객체에서 사용한 json 파일을 살펴보겠습니다.
// src/translation/ko/translation.json
{
"question": "사슴이 눈이 좋으면?",
"answer": "굿아이디어~ (good eye deer~)"
}
// src/translation/en/translation.json
{
"question": "what is it called if a deer has a good eye sight?",
"answer": "Good idea~ (good eye deer~)"
}
편의상 나눠진 두 개의 json 파일을 한번에 작성했습니다. 저는 영어와 한국어, 두 언어를 지원할 예정이기에 해당하는 json 파일들을 생성했습니다. 이때 중요한 점은 key 값을 동일하게 설정해야 한다는 것입니다.
이제 App.js로 이동 후 최종적으로 적용해보겠습니다.
// App.js
import { useTranslation } from 'react-i18next';
import i18n from './translation/i18n';
import './App.css';
function App() {
const { t } = useTranslation();
const changeLanguage = (lang) => {
i18n.changeLanguage(lang);
};
return (
<div className="container">
<h1>{t('question')}</h1>
<h1>{t('answer')}</h1>
<div>
<button onClick={() => changeLanguage('ko')}>ko</button>
<button onClick={() => changeLanguage('en')}>en</button>
</div>
</div>
);
}
export default App;
useTranslation 훅을 불러옵니다 그리고 해당 훅으로부터 t 함수를 가져옵니다.
t함수는 번역 리소스의 객체의 key 값을 인수로 받으면, 현재 선택된 언어에 해당하는 번역본을 가져와주는 역할을 합니다. 즉 현재 언어가 'ko'이고 t('question') 라면, ko에 해당하는 키(question) 값인 "사슴이 눈이 좋으면?"을 가져오는 겁니다. 만약 현재 언어가 'en'이라면 이에 해당하는 값을 가져오겠지요.
이러한 이유 때문에 번역 리소스를 정의할 때 key 값을 동일하게 설정했던 것입니다.
언어를 선택하기 위한 간단한 핸들러도 만들었습니다.
const changeLanguage = (lang) => {
i18n.changeLanguage(lang);
};
앞서 설정했던 i18n 인스턴스의 changeLanguage('언어') 메서드를 통해 언어를 변경할 수 있습니다.
ko를 전달하면 ko에 해당하는 언어의 json을 가져올 것이고, en을 전달하면 en에 해당하는 언어의 json을 가져올 것입니다. 그런데 만약 제가 설정해놓지 않았던 임의의 'aaa'라는 값을 전달하면 어떻게 될까요?
위의 코드에서는 en에 해당하는 json을 가져올 것입니다. 그 이유는 i18n 인스턴스에서 fallbackLng의 값을 'en'으로 설정했기 때문입니다. "설정된 언어(lng)에서 번역을 찾을 수 없는 경우, 기본 언어로 사용할 언어를 지정합니다."의 의미가 바로 이것입니다.
이제 최종 결과를 확인해 보겠습니다.
선택한 언어별로 다른 언어가 렌더링 되는 것을 확인할 수 있습니다.
투두리스트에 적용해 보자!
https://best-todolist-ever.netlify.app/
(이유는 모르겠는데 티스토리 앱에서는 안 들어가지네요🤔)
개쩌는 투두리스트!
best-todolist-ever.netlify.app
작년에 만들었던 투두리스트에 i18n을 통해 영어를 적용해 봤습니다. 아래의 select 태그를 통해 언어를 변경할 수 있습니다.
이거 적용하는 김에 반응형과 미디어 쿼리도 적용해 봤는데, 맘에 듭니다 ㅎ.ㅎ 물론 이미지가 느리게 뜨는 건 여전히 스트레스입니다.
결론
i18next 라이브러리를 통해 서비스에서 다국어 지원하는 방법을 알게 되었습니다.
하지만 이건 프론트측에서 단어를 미리 정의해서 변경하는 방식이다 보니, 만약 백엔드 api를 통해 받아오는 데이터의 경우는 번역을 어떻게 해야 할 지에 대한 고민이 생겼습니다.
어떤 데이터가 올 지 모르고, 안다고 해도 모든 데이터를 미리 정의할 수는 없으니까요
아무래도 백엔드에서 번역을 해서 보내주는 방법 밖에 없으려나요? 아무튼 그건 나중에 알아보는 걸로~~
'개발 지식' 카테고리의 다른 글
형태소 분석기 ‘바른’ REST 방식으로 사용하기 (1) | 2024.12.11 |
---|---|
Chakra(차크라) UI를 사용해 보자(with React) (0) | 2024.07.18 |
[TS] interface와 type alias의 차이점은 무엇인가? (0) | 2024.07.06 |