Next app에 다국어 적용하기
다국어 적용의 필요성
국내에서만 서비스 하는 것이 아니라면 언제나 다국어 적용이 필요해진다.
React나 Vue에서도 각각 맞는 i18n 모듈이 있고, 공식문서를 확인하며 따라하면 충분히 적용된다.
Next.js에서도 간편하게 사용할 수 있는 모듈이 있어서 해당 모듈에 대해서 설치하고 간단히 적용하는 방법에 대해서 적어볼 것이다.
적용해볼 모듈은 next-i18next이다.
설치하고 적용해보기
npm install next-i18next
해당 명령어로 설치할 수 있다.
이제 번역 컨텐츠를 구성해보자.
만약에 한국어와 영어로 한다고 생각한다면, public 폴더에 en과 ko를 만들어줄 수 있다.
.
└── public
└── locales
├── en
| └── common.json
└── ko
└── common.json
다른 페이지들이 추가된다면 common.json과 더불어 home.json 등의 파일을 만들어주면 된다.
기본적으로 common.json을 만들어두는 게 좋다. 왜냐하면 common.json이 없으면 next-i18next는 Default namespace Not Found라는 에러를 뱉어낼 것이기 때문이다. 따로 Default namespace를 잡아주지 않을 것이라면 공통된 요소에 쓰는 컨텐츠는 common.json으로 사용하면 된다.
이제 해야할 것은 next-i18next.config.js 파일을 루트 디렉토리에 만드는 것이다.
// next-i18next.config.js
module.exports = {
i18n: {
defaultLocale: "en",
locales: ["en", "ko"],
},
};
defaultLocale은 en으로 잡고, 사용하는 locale은 en과 ko를 입력해주었다.
주의할 점
해당 파일의 역할과 Locale의 이름에 대해서 알아두어야 할 것이 있다.
우선 next.js는 브라우저 렌더링이 아니라 서버 사이드 렌더링이다. 그래서 react나 vue로 i18n을 넣었을 때와는 다른 상황을 겪게된다. 그건 default값을 전달할 때 다르다는 것이다. 브라우저 렌더링이라면 디폴트 값을 navigator.language 등을 통해서 브라우저의 언어를 갖고오고 해당 값을 전달할 것이다. 그러면 한국어 사용자라면 맨 처음 화면이 한글로 보여질 것이고, 영어권 사용자라면 영어로 보여지도록 만들어 줄 수 있을 것이다.
그러나 서버사이드 렌더링에서는 navigator.language을 사용할 수 없다.
서버사이드렌더링에서 사용하는 것은 요청 Header에 담기는 Accept-Language이다
기본적으로 요청을 할 때 헤더에 Accept-Language가 담긴다.
이미지가 아니라 실제로 확인하고 싶다면 크롬 개발자 도구를 켜고, 네트워크 패널을 켠채로 요청을 해보자.
그리고 next-i18next는 Accept-Language에 맞게 우선적으로 보여주지만 거기에 없다면 디폴트 값을 보여준다.
한국어는 Accept-Language에서 보통 ko로 표현되므로 ko로 설정해주자.
여기서는 디폴트로 설정된 locale이 “/” 이고, ko는 “/ko”가 된다.
next.config.js 추가하기
// next.config.js
const { i18n } = require("./next-i18next.config");
module.exports = {
i18n,
};
아까 만든 next-i18next.config에서 i18n을 갖고와서 i18n을 전달해주면 된다.
이제는 프로젝트에 적용시켜 보자.
// _app.js
import { appWithTranslation } from "next-i18next";
const MyApp = ({ Component, pageProps }) => <Component {...pageProps} />;
export default appWithTranslation(MyApp);
_app에 기본적으로 MYApp이라는 컴포넌트가 있을 것이다. 해당 컴포넌트를 appWithTranslation으로 감싸주면 된다.
그리고 페이지에서는 getStaticProps를 불러와주자.
// pages/index.js
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
export const getStaticProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ["common"])),
},
});
마지막으로는 useTranslation 훅을 통해서 t 함수를 불러와서 적용시켜주면 된다.
import { useTranslation } from "next-i18next";
export const Home = () => {
const { t } = useTranslation("common");
return (
<div>
<p>{t("Header")}</p>
</div>
);
};
내가 만든 예시
내가 만든 예시를 통해 좀 더 살펴보자.
// public/locales/en/common.json
{
"h1": "A simple example",
"change-locale": "Change locale",
"to-second-page": "To second page",
"error-with-status": "A error occurred on server",
"error-without-status": "An error occurred on the server",
"title": "Home | next-i18next"
}
위와 같이 영어, 한국에 대한 common.json을 만들어두었다.(번역 컨텐츠 작업)
next-i18next.config.js와 next.config.js, _app.jsx는 위와 똑같이 적었다.
// pages/index.js
import Link from "next/link";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { useTranslation } from "next-i18next";
const Home = () => {
const { t } = useTranslation("common");
return (
<div>
<p>{t("h1")}</p>
<p>{t("change-locale")}</p>
<p>{t("to-second-page")}</p>
<p>{t("error-with-status")}</p>
<p>{t("error-without-status")}</p>
<p>{t("title")}</p>
<div>
<Link href="/" locale="en">
<button>영어</button>
</Link>
<Link href="/" locale="ko">
<button>한국어</button>
</Link>
</div>
</div>
);
};
export const getStaticProps = async ({ locale }) => {
console.log("locale of getStaticProps", locale);
return {
props: {
...(await serverSideTranslations(locale, ["common"])),
},
};
};
export default Home;
해당 코드에서는 언어를 바꾸는 버튼도 들어가 있다.
import Link from "next/link";
<Link href="/" locale="en">
<button>영어</button>
</Link>
<Link href="/" locale="ko">
<button>한국어</button>
</Link>
링크 컴포넌트를 갖고와서 locale을 변경하면 해당 언어에 맞게 변경되는 것을 확인할 수 있다.
Leave a comment