🎯 Goal
- Next.js에서 next-i18next를 사용할 때, ES 모듈 관련 에러 해결
⚠️ 문제 현상
프로젝트 서버를 실행한 후 http://localhost:3000 으로 접속을 해보면
react-i18next:: You will need to pass in an i18next instance by using initReactI18next
다음과 같은 에러가 발생합니다.
react-i18next:: You will need to pass in an i18next instance by using initReactI18next
🔑 에러 원인
next-i18next가 CommonJS 방식으로 작성되었기 때문에,
ES 모듈 환경에서 사용하면 충돌이 발생하기 때문이다.
ES 모듈 환경에서 require()를 사용할 수 없으므로,
이로 인해 i18next 인스턴스가 초기화되지 않는다.
💊 해결 방법
CommonJS 모듈 방식 사용
CommonJS는 Node.js 에서 오랫동안 사용된 모듈 시스템입니다.
ES 모듈은 최신 표준이지만, next-i18next는 아직 CommonJS 방식을 사용하므로 충돌 발생
✅ 다국어 라이브러리 설치
- i18next : 다국어 번역을 처리하는 핵심 라이브러리
- react-i18next : React에서 i18next를 쉽게 사용 (useTranslation 훅 제공)
- next-i18next : Next.js와 i18next를 연결해 다국어를 지원하는 라이브러리
useTranslation 훅을 사용하여 쉽게 텍스트를 번역할 수 있습니다.
react-i18next의 기능을 모두 포함하고 있기 때문에, next-i18next만 설치해도 다국어 기능 사용 가능
npm i next-i18next react-i18next i18next
⚙️ package.json 설정 수정 (CommonJS 사용)
"type": "commonjs" ➡️ CommonJS 방식 사용
// ▶ ⚙️package.json
{
"name": "day30_i18next",
"version": "1.0.0",
"main": "index.js",
"type": "commonjs",
"scripts": {
"dev": "npx next dev",
"build": "npx next build",
"start": "npx next start",
"i18n": "next-i18next",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"i18next": "^23.15.2",
"next": "^14.2.15",
"next-i18next": "^15.3.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^15.0.3"
},
"devDependencies": {
"@types/node": "22.7.5",
"@types/react": "18.3.11",
"typescript": "5.6.3"
}
}
⚙️ next-i18next.config.js 설정 수정 (next-i18next 설정 파일)
CommonJS 방식으로 작성합니다.
// ▶ ⚙️next-i18next.config.js
const path = require('path'); // path 모듈을 require로 가져오기
const nextI18NextConfig = {
i18n: {
defaultLocale: 'ko',
locales: ['en', 'ko'], // 지원할 언어를 배열로 지정
},
localePath: path.resolve('./public/locales'), // JSON 파일 경로
};
module.exports = nextI18NextConfig; // CommonJS 방식으로 모듈 내보내기
⚙️ next.config.js 설정 수정
CommonJS 방식으로 next-i18next 설정 파일을 가져옵니다.
// ▶ ⚙️next.config.js
// ▶ next-i18next 설정 파일을 가져오기
const nextI18NextConfig = require('./next-i18next.config.js');
// ▶ Next.js 설정 내보내기
module.exports = {
reactStrictMode: true,
env: {
API_PATH: "https://www.naver.com"
},
pageExtensions: ["js", "jsx", "ts", "tsx"],
trailingSlash: false,
poweredByHeader: false,
outputFileTracing: true,
// ▶ i18n 설정 추가
// 가져온 설정에서 i18n 부분만 사용
i18n: nextI18NextConfig.i18n,
};
🗃️ 다국어 폴더 및 파일 생성
🗃️public 폴더 내에 🗂️locales 폴더를 생성한 후,
각 언어별로 폴더를 만든 후 각 언어별 JSON 파일을 추가합니다.
├── public
│ └── locales
│ ├── ko
│ │ └── common.json
│ └── en
└── └── common.json
- 국문 (ko)
// ▶ 🗃️ public/locales/ko/common.json
{
"welcome": "우리 사이트에 오신 것을 환영합니다!",
"description": "이것은 다국어 사이트입니다."
}
- 영문 (en)
// ▶ 🗃️ public/locales/en/common.json
{
"welcome": "Welcome to our site!",
"description": "This is a multi-language site."
}
📜 다국어 적용하기
📦 _app.tsx 설정
appWithTranslation 함수 사용하여 전체 애플리케이션에 다국어 설정을 적용합니다.
// ▶ 📦 pages/_app.tsx
import React from 'react';
import { appWithTranslation } from 'next-i18next'; // 다국어 지원 기능을 추가하는 함수 가져오기
// ▶ MyApp 컴포넌트 정의
// Component : 현재 렌더링할 페이지의 컴포넌트
// pageProps : 현재 페이지에 전달된 속성(props)
function MyApp({ Component, pageProps }) {
// ● 현재 페이지의 컴포넌트를 렌더링하고, 전달된 속성(props)을 모두 전달
return <Component {...pageProps} />
}
// ▶ MyApp을 다국어 지원으로 감싸서 내보냄
export default appWithTranslation(MyApp);
🔗 index.tsx 페이지 설정
다국어 기능을 위해 next-i18next 라이브러리에서 필요한 모듈을 임포트합니다.
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
getServerSideProps 함수(SSR)를 사용하여 서버 측에서 번역 데이터를 가져옵니다.
이 함수는 비동기(async)로 작동하며, 페이지가 사용자에게 보여지기 전에 실행됩니다.
이 함수 내에서 serverSideTranslations 호출하여
사용자가 선택한 언어에 맞는 번역 데이터를 가져옵니다.
이렇게 가져온 데이터는 페이지가 로드되기 전에 준비되므로,
이후 useTranslation 훅을 사용할 수 있습니다.
이때 i18next 인스턴스는 이미 준비된 상태이므로, 번역 오류 없이 다국어 기능이 정상적으로 작동합니다.
// ▶ 🔗 pages/index.tsx
import React from 'react';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; // 서버에서 번역 데이터 가져오는 함수
import { useTranslation } from 'next-i18next'; // 클라이언트에서 번역을 사용하는 훅
import { useRouter } from 'next/router'; // Next.js의 라우터 훅을 임포트
/*
[다국어 페이지]
언어에 따라 화면에 맞는 텍스트(번역) 표시
⇒ http://localhost:3000/ko ➡️ 국문 페이지
⇒ http://localhost:3000/en ➡️ 영문 페이지
*/
// ▶ 경로가 바뀔 때마다 번역본을 가져오기 위해서는 getServerSideProps가 반드시 필요
// locale : 현재 페이지의 언어 정보 ('ko' 또는 'en')
export async function getServerSideProps({ locale }) {
console.log("locale : " ,locale);
// ● serverSideTranslations : 서버에서 번역 파일을 로드하여 props로 전달
return {
props: {
...(await serverSideTranslations(locale , ['common'])), // 'common' 네임스페이스로 번역 데이터 가져옴
},
};
}
export default function Home() {
// ▶ 'common' 파일에 있는 번역을 사용
// 번역 함수 t와 i18n 객체 가져오기
const { t, i18n } = useTranslation('common');
// ▶ Next.js의 라우터 사용
// 라우터 인스턴스 생성
const router = useRouter();
// ▶ 언어를 변경하는 함수 (사용자가 버튼을 클릭하면 언어가 변경됨)
// i18next의 changeLanguage 함수 호출하여 언어 변경
const changeLanguage = (lang) => {
i18n.changeLanguage(lang).then(() => { // 언어 변경 비동기 작업이므로 then을 사용하여 완료 후 작업 수행
// ● 페이지를 새로고침 없이 번역된 내용을 가져오기 위해 현재 경로를 변경
// 언어 변경이 완료된 후 현재 경로를 변경
router.replace(router.pathname, router.asPath, { locale: lang });
});
};
return (
<div>
{/* 언어 변경 버튼 */}
<button onClick={() => changeLanguage('en') }>영문</button>
<button onClick={() => changeLanguage('ko') }>국문</button>
{/* 번역된 텍스트 표시 */}
<h1>{t('welcome')}</h1> {/* common.json 파일의 "welcome" 키값에 해당하는 번역된 텍스트 */}
<p>{t('description')}</p> {/* common.json 파일의 "description" 키값에 해당하는 번역된 텍스트 */}
</div>
);
}
📝 구현 결과
이제 다국어 기능이 정상적으로 작동하며, 버튼 클릭을 통해 언어를 변경할 수 있습니다.
이 방법을 통해 next-i18next를 Next.js 프로젝트에서 성공적으로 사용할 수 있습니다.
🚀 샘플 코드 가이드
1) 프로젝트 클론
https://github.com/KwonSsohyun/FED_WEB_2024/tree/main/study/day30_i18next
2) 의존성 설치
Visual Studio Code에서 다운로드한 프로젝트 폴더를 연 후,
터미널(Ctrl+Shift+`)에서 아래 명령어를 실행하여 필요한 패키지를 설치합니다.
npm i
3) 개발 서버 실행
터미널(Ctrl+Shift+`)에서 아래 명령어를 실행하여 개발 서버를 실행합니다.
npm run dev
4) 웹사이트 확인
http://localhost:3000
'📌 Front End > └ React' 카테고리의 다른 글
[React] 리액트 UI 컴포넌트 라이브러리 - Material UI, Ant Design, Chakra UI, Blueprint JS, Blueprint UI (2) | 2024.11.26 |
---|---|
[React] Next.js PM2 배포 가이드(서버 자동 재시작) - 리눅스, 윈도우 설정차이점 (0) | 2024.11.11 |
[React] Next.js로 React와 TypeScript 환경 설정하기 (4) | 2024.10.11 |
[React] 서버리스 아키텍처와 클라우드 컴퓨팅 - IaaS, PaaS, BaaS, FaaS (7) | 2024.10.10 |
[React] 리액트에서 Nivo Chart 데이터 시각화 (3) | 2024.10.06 |