Next.js 프로젝트에서 i18n으로 다국어 사이트를 만들어보자
목차
현재 사이트를 한국 사용자뿐만 아니라 글로벌 사용자에게도 지원되게끔 해보고 싶었다.
(볼 사람이 있을까 싶지만, 그냥 한 번 해보고 싶었다.)
이를 위해 웹사이트에 다국어 지원, 즉 국제화(Internationalization, i18n)를 도입하기로 했다.
이 사이트는 Next.js 프로젝트였기에 널리 사용되는 라이브러리인 next-i18next
를 선택했다.
i18n 및 next-i18next의 특징
- Next.js와의 통합성: next-i18next 라이브러리를 통해 Next.js의 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG)과도 잘 호환된다.
- 사용 편의성: 러닝 커브가 낮고, 기존 코드에 쉽게 적용할 수 있다.
- 기능성: 로케일 기반 라우팅, 번역 파일 관리, 복수형 처리 등 다양한 기능을 지원한다.
Next.js(Page Router) 프로젝트에 next-i18next
를 사용해 i18n을 적용하는 과정을 간단하게 정리해보았다.
라이브러리 설치하기
먼저 next-i18next
와 react-i18next
를 설치한다.
yarn add next-i18next react-i18next
i18n 설정하기
다음으로 i18n이 어떻게 동작할지 정의하는 설정 파일이 필요하다.
프로젝트 최상단에 next-i18next.config.js
파일을 생성하고 아래와 같이 기본 설정을 정의한다.
// next-i18next.config.js module.exports = { i18n: { defaultLocale: 'ko', locales: ['ko', 'en'], defaultNS: "common", }, };
속성 | 설명 |
---|---|
defaultLocale | 언어 설정이 없는 경우 보여줄 기본 언어 |
locales | 우리 서비스가 지원할 언어 목록 |
defaultNS | 네임스페이스를 생략했을 때 기본으로 로드할 네임스페이스 문자열 혹은 배열 |
ns | i18next가 미리 로드(preload) 할 네임스페이스 문자열 혹은 배열 |
이제 이 설정을 next.config.js
에 적용해야 한다.
// next.config.js const { i18n } = require('./next-i18next.config'); /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, i18n, // 여기에 i18n 설정을 추가 }; module.exports = nextConfig;
i18n 적용하기
앱 전역에서 i18n 기능을 사용하려면 _app.tsx
파일을 수정해야 한다.
next-i18next
에서 제공하는 appWithTranslation
HOC로 앱 컴포넌트를 감싸주면 된다.
// src/pages/_app.tsx import type { AppProps } from 'next/app'; import { appWithTranslation } from 'next-i18next'; function App({ Component, pageProps }: AppProps) { return <Component {...pageProps} />; } // appWithTranslation으로 앱을 감싸준다. export default appWithTranslation(App);
번역 파일 만들기
이제 실제 번역 텍스트가 담길 파일을 만들 차례다.
next-i18next
는 기본적으로 public/locales/[locale]/[namespace].json
에서 번역 파일을 불러온다.
나는 한국어와 영어를 지원하기 위해 locales 하위에 ko/common.json
과 en/commons.json
파일을 생성했다.
아래는 번역 텍스트 정의 예시이다.
// public/locales/ko/common.json { "hello": "안녕하세요, 서정민입니다.", "welcome": "환영합니다" }
// public/locales/en/common.json { "hello": "Hello!, I'm Jeongmin Seo, "welcome": "Welcome" }
페이지에서 번역 사용하기
이제 모든 설정이 끝났고, 페이지에 번역 텍스트를 적용해 볼 차례다.
페이지 및 하위 컴포넌트에서 다국어를 적용하려면,
먼저 해당 페이지에서 필요로 하는 다국어 파일들과 서버 사이드 렌더싱 시 사용할 언어를 알려 줘야 한다.
getStaticProps
나 getServerSideProps
에서 serverSideTranslations
를 호출해서 이 작업을 처리할 수 있다.
아래 코드를 살펴보자.
// src/pages/index.tsx import { useTranslation } from 'next-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import type { GetStaticProps, NextPage } from 'next'; const Home: NextPage = () => { const { t } = useTranslation('common'); // 사용할 네임스페이스를 지정 return ( <div> <h1>{t('hello')}</h1> <p>{t('welcome')}</p> </div> ); }; // 방법 1. 빌드 타임에 번역 파일을 불러온다. export const getStaticProps: GetStaticProps = async ({ locale }) => ({ props: { ...(await serverSideTranslations(locale ?? 'ko')), }, }); // 방법 2. 페이지 요청마다 번역 파일을 불러온다. export const getServerSideProps: GetServerSideProps = async ({locale}) => ({ props: { ...(await serverSideTranslations(locale ?? 'ko')), }, }); export default Home;
먼저 SSR이나 SSG 둘 중 하나의 방법으로 서버 사이드에서 사용해야하는 다국어 정보를 인지시켜준다.
예제에서는 serverSideTranslations 호출 시 네임스페이스(ns) 인자를 생략한 것을 볼 수 있다.
이 경우, next-i18next.config.js에서 별도로 미리 로드할 NS를 설정하지 않았다면 defaultNS에 해당하는 다국어 파일만 로드된다.
현재는 config에서 모든 NS를 미리 로드하는 방식으로 구현했지만,
공통된 NS만 defaultNS로 분리하고, 페이지별로 필요한 네임스페이스만 지정하는 방식이 번들링 최적화에도 유리하기 때문에 해당 방식을 권장한다고 한다.
이제 최종적으로 페이지나 다국어 처리가 필요한 하위 컴포넌트에서 useTranslation
훅을 호출해준다.
useTranslation
에서 반환하는 t
함수를 통해 현재 locale에 맞는 번역 텍스트에 접근할 수 있다.
t
함수의 첫 번째 인자는 JSON 파일에 정의한 key
다.
언어 전환 기능 구현하기
next-i18next
는 URL 경로(e.g., /ko/about
, /en/about
)를 기반으로 언어를 감지한다. 사용자는 URL을 변경하여 언어를 바꿀 수 있다.
Next.js의 Link
컴포넌트를 이용해 사용자가 언어를 전환할 수 있게 하는 간단한 예제다.
import Link from 'next/link'; import { useRouter } from 'next/router'; const LanguageSwitcher = () => { const router = useRouter(); const { locales, locale: activeLocale } = router; return ( <div> {locales?.map((locale) => ( <Link key={locale} href={router.pathname} locale={locale}> <a style={{ fontWeight: activeLocale === locale ? 'bold' : 'normal' }}> {locale.toUpperCase()} </a> </Link> ))} </div> ); };
마무리
위 과정을 통해 블로그에서 영어 사용자들을 위한 콘텐츠도 점차적으로 제공할 수 있게 되었다.
Next.js 프로젝트에서 i18n 적용 시 핵심은 다음과 같다고 생각한다.
- 번역 파일 관리: 프로젝트가 커질수록 번역 파일이 복잡해질 수 있다. 네임스페이스(기능, 페이지 등) 단위로 파일을 분리해서 관리하는 것이 중요하다.
serverSideTranslations
: 이 함수는 Next.js에 다국어를 통합하는 데 핵심 역할을 한다. 번역이 필요한 모든 페이지에서 반드시 올바르게 호출해야 한다.
다국어 지원뿐만 아니라, SEO에서의 이점도 있다.
{domain}/en/page
와 같은 경로 기반의 방식은 검색 엔진이 각 언어별로 페이지를 인덱싱할 수 있게 해주므로 검색 엔진 최적화에 유리하다.
i18n 설정이 처음에는 번거로워 보일 수 있지만, next-i18next
덕분에 매우 간단하게 다국어를 지원할 수 있게 되었다.