Written by
JJoo
on
on
react에 다국어 기능 적용하기(i18next)
react에 다국어 기능 적용하기
react 프로젝트에 i18next를 사용하여 다국어 기능을 구현해보자.
일단 패키지 설치
i18next와 react-i18next 두가지를 설치해준다.
npm install react-i18next i18next
타입스크립트에 적용할때 설치
npm i i18next @types/i18next react-i18next @types/react-i18next
자동으로 사용자의 브라우저 언어를 인식하기 위한 모듈도 설치해준다. i18next-browser-languagedetector
npm install i18next-browser-languagedetector
최상단 루트에 i18n.tsx
를 생성한다.
i18n.tsx
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import enTranslation from './locales/en.json'; // 바로 밑에서 만들어줄 언어시트
import koTranslation from './locales/ko.json'; // 바로 밑에서 만들어줄 언어시트
const resources = {
en: {
translation: enTranslation,
},
ko: {
translation: koTranslation,
},
};
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources,
fallbackLng: 'ko',
interpolation: {
escapeValue: false,
},
});
export default i18n;
/src/locales
폴더를 생성 후 en.json
, ko.json
파일을 생성한다.
/src/locales/en.json
{
"test":"lang test"
}
/src/locales/ko.json
{
"test":"언어 테스트"
}
_app.js
에 적용
SSR 프로젝트에서는 <I18nextProvider>
로 랩핑해줘야 한다.
_app.js
에서 <I18nextProvider>
로 감싸고 위에서 만든 i18n.tsx
를 불러와 props
로 내려준다.
import React, { useEffect, useState } from 'react';
import { AppProps } from 'next/app';
import { GlobalStyle } from '../styles/grobal-style';
import i18n from '@i18n';
import { I18nextProvider } from 'react-i18next';
function MyApp({ Component, pageProps }: AppProps) {
const [isMounted, setIsMounted] = useState<boolean>(false);
useEffect(() => {
setIsMounted(true);
}, []);
return (
<>
{isMounted && (
<I18nextProvider i18n={i18n}>
<GlobalStyle />
<Component {...pageProps} />
</I18nextProvider>
)}
</>
);
}
export default MyApp;
여기까지 언어변환을 사용할 기본적인 셋팅을 끝냈다.
여기서 세가지 방법으로 적용할 수가 있다.
- render props인 Translate 사용
- hook사용
- hoc 사용
방법 1 - render props인 Translate
import React from 'react';
import Head from 'next/head';
import { Translation } from 'react-i18next';
function Main() {
return (
<div>
<Head>
<title>Web Admin Skeleton</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<TranslationButton />
<Translation>{(t) => <p>{t('test')}</p>}</Translation>
index
</main>
</div>
);
}
export default Main;
Translation을 사용해서 번역할 부분을 감싸준다.
언어변환 버튼 컴포넌트 Translation.tsx
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import i18next from 'i18next';
const Translation = () => {
const [language, setLanguage] = useState('ko');
useEffect(() => {
const initLang =
(window.localStorage.i18nextLng.substring(0, 2) === 'ko' && 'ko') || 'en';
setLanguage(initLang);
});
const toggleTrans = (lang) => {
setLanguage(lang);
if (language != lang) {
i18next.changeLanguage(lang, (err) => {
if (err) return console.log('something went wrong loading', err);
});
}
};
return (
<div>
<TransBox>
<TransButton onClick={() => toggleTrans('ko')}>
<p>KO</p>
</TransButton>
<span> | </span>
<TransButton onClick={() => toggleTrans('en')}>
<p>EN</p>
</TransButton>
</TransBox>
</div>
);
};
const TransBox = styled.div`
display: flex;
flex-direction: row;
`;
const TransButton = styled.button``;
export default Translation;
방법 2 - hook 사용
import React from 'react';
import Head from 'next/head';
import TranslationButton from './translation/translation';
import { useTranslation } from 'react-i18next';
function Main() {
const { t } = useTranslation();
return (
<div>
<Head>
<title>Web Admin Skeleton</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<TranslationButton />
<p>{t('test')}</p>
main
</main>
</div>
);
}
export default Main;
언어변환 버튼 컴포넌트 Translation.tsx
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import { useTranslation } from 'react-i18next';
const Translation = () => {
const { i18n } = useTranslation();
const [language, setLanguage] = useState('ko');
useEffect(() => {
const initLang =
(window.localStorage.i18nextLng.substring(0, 2) === 'ko' && 'ko') || 'en';
i18n.changeLanguage(initLang);
setLanguage(initLang);
}, []);
const onChangeLang = (lang: string) => {
i18n.changeLanguage(lang);
setLanguage(lang);
};
return (
<div>
<TransBox>
{language}
<TransButton onClick={() => onChangeLang('ko')}>
<p>KO</p>
</TransButton>
<span> | </span>
<TransButton onClick={() => onChangeLang('en')}>
<p>EN</p>
</TransButton>
</TransBox>
</div>
);
};
const TransBox = styled.div`
display: flex;
flex-direction: row;
`;
const TransButton = styled.button``;
export default Translation;
Discussion and feedback