처음 일을 시작하고 jsx나 tsx 파일에 텍스트를 직접 마크업하지 않은 것을 보고 멘붕이 왔었다. t( '...' )
이런 식으로 내용을 적용한 것을 볼 수 있었는데, 이게 i18n을 사용해서 국제화 작업을 한 것임을 알아냈을때 유레카를 외치고 싶을 정도였다. ㅋㅋㅋㅋㅋ 적응되니 너무너무 편하고 좋은 라이브러리! 다시 한번 정리해보자.
i18next는 자바스크립트에서 국제화 프레임워크로 쓰인다. Node.js, PHP, iOS, Android 및 기타 플랫폼과 함께 i18next를 사용할 수도 있다.
프로젝트에 패키지를 설치한다.
# npm
$ npm install react-i18next --save
# yarn
$ yarn add react-i18next
import React from "react";
import ReactDOM from "react-dom";
import i18n from "i18next";
import { useTranslation, initReactI18next } from "react-i18next";
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
resources: { // 여기에 사용할 언어와 키와 번역될 키 값을 넣으면 된다.
en: {
translation: {
"Welcome to React": "Welcome to React and react-i18next"
}
}
},
lng: "en",
fallbackLng: "en",
interpolation: {
escapeValue: false
}
});
function App() {
const { t } = useTranslation();
return <h2>{t('Welcome to React')}</h2>; // 이렇게 지정된 키를 적어 사용한다.
}
// append app to dom
ReactDOM.render(
<App />,
document.getElementById("root")
);
위 App
이 실행되면 <h2>Welcome to React and react-i18next</h2>
가 나온다! 보통은 번역할 내용이 많기 때문에 따로 파일을 빼서 import 하여 사용하는 것이 일반적이다. 위 코드를 하나씩 뜯어보자.
i18next.use(module)
use 함수는 i18next에 추가적인 플러그인을 적용할때 사용된다.
import i18next from 'i18next';
import Backend from 'i18next-http-backend';
import Cache from 'i18next-localstorage-cache';
import postProcessor from 'i18next-sprintf-postprocessor';
import LanguageDetector from 'i18next-browser-languagedetector';
i18next
.use(Backend)
.use(Cache)
.use(LanguageDetector)
.use(postProcessor)
.init(options, callback);
위 플러그인 중에서 LanguageDetector
만 사용해봤는데, 여기서 자세한 내용을 볼 수 있다. 대략 유저가 브라우저에서 어떤 언어를 쓰고 있는지 detect 하는 플러그인이라고 생각하면 된다. path를 1순위로, 그 다음 브라우저의 세팅을 2순위로 언어를 detect 한다면 아래와 같이 사용할 수 있을 것이다.
import i18next from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
i18next.use(LanguageDetector).init({
detection: { order: ['path', 'navigator'] }
});
위 두가지 옵션 외에도 쿠키나 스토리지, html 태그 등으로 언어를 detect 할 수 있다.
import i18n from "i18next";
import detector from "i18next-browser-languagedetector";
import { reactI18nextModule } from "react-i18next";
import translationEN from '../public/locales/en/translation.json';
import translationDE from '../public/locales/de/translation.json';
// the translations
const resources = {
en: {
translation: translationEN
},
de: {
translation: translationDE
}
};
i18n
.use(detector)
.use(reactI18nextModule) // passes i18n down to react-i18next
.init({
resources,
lng: "en",
fallbackLng: "en", // detected lng이 불가능 할때 en을 사용하겠다.
keySeparator: false, // 'messages.welcome' 와 같은 키 형식의 form을 사용할지 여부
interpolation: {
escapeValue: false // react already safes from xss
// xss가 스크립트 코드를 삽입하여 사용자를 대상으로 한 공격이라고 하는데 이건 잘 모르겠다. 흠...
}
});
export default i18n;
useTranslation(hook)
import React from 'react';
import { useTranslation } from 'react-i18next';
export function MyComponent() {
const { t, i18n } = useTranslation();
// or const [t, i18n] = useTranslation();
return <p>{t('my translated text')}</p>
}
함수형 컴포넌트에서 t function
이나 i18n
인스턴스를 사용할 수 있게 해주는 훅이다. t function
은 위에서 봤듯이 컨텐츠에 국제화 작업을 하기 위해 사용되고, i18n
인스턴스는 언어를 바꾸기 위해 사용되기도 한다.
i18n.changeLanguage('en-US');
또는 아래와 같이 언어에 따라 스타일 값이 달라져야 할때도 사용할 수 있다. 언어를 detect하기 때문!
const Title = styled.p`
background-image: url(${imgPathPrefix}/intro-title${i18n.language === 'en' ? '-en' : ''}.png);
background-size: ${i18n.language === 'en' ? '15vw auto' : '18vw auto'};
background-repeat: no-repeat;
width: ${i18n.language === 'en' ? '15vw' : '18vw'};
height: ${i18n.language === 'en' ? '25.6vw' : '19.2vw'};
`;
i18n을 사용할 때 디렉토리 트리를 단순화한 다이어그램이다.
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { kr, en } from './locales';
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: { kr, en },
fallbackLng: ['kr', 'en'],
interpolation: { escapeValue: false },
detection: { order: ['path', 'navigator'] }
});
export default i18n;
import * as localeKr from './kr';
import * as localeEn from './en';
export const kr = { ...localeKr };
export const en = { ...localeEn };
export default { kr, en };
export { default as main } from './main';
export { default as header } from './header';
export { default as footer } from './footer';
export default {
mode: 'en',
add: 'Add',
cancel: 'Cancel',
placeholder: {
login: 'Please log in first',
comment: 'Leave a comment',
},
}
export default {
mode: 'kr',
add: '장바구니에 담기',
cancel: '취소하기',
placeholder: {
login: '로그인해주세요',
comment: '댓글을 남겨주세요',
},
}
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
export default function Main() {
const { t } = useTranslation('main');
return <h2>{t('placeholder.login')}</h2>;
// '로그인해주세요' 또는 'Please log in first'가 컨텐츠로 적용
}
참고자료 : https://react.i18next.com/
감사합니다 자꾸 언어 감지가 안 되었는데 이 글 보고 해결했어요!