솔미는 성장중
다국어 적용하기 (next.js & i18n) 본문
8개국어 다국어를 적용해야 하는 작업이 나에게 들어왔다..!
한번 설계를 잡아두면 계속해서 같은 방식으로 사용해 나갈 것이기에 효율적인 설계를 하고 싶은 마음이 컸다.
고려해야할 것은 크게 2가지가 있다.
첫번째로는 이용자의 국가를 판별하는 것, 두번째는 어떻게 다국어 콘텐츠를 제공할 것인지이다.
1. 이용자의 국가 판별
- 접속 ip대역
: 접속 ip대역을 통해 자동으로 언어를 설정하는것은 비추천 합니다. 사용자가 직접 언어를 선택해서 사용할 수 있게 하는게 제일 좋은거 같습니다. 그 이유는 사용자가 잠시 해외에 거주중인 상태에서 접속한다면 한국어로 보고싶어도 대역이 해외로 잡혀서 자동으로 언어가 전환되면 오히려 이런 유저들은 불편함을 초래할 수 있기 때문입니다!
그래서?
- 모바일 설정 언어를 기본으로 설정해주는 방식
- 직접 선택하는 방식
이 2가지 방식은 혼용하는 것이 베스트라는 생각입니다.
2. 어떻게 다국어 콘텐츠를 제공할 것인가? (기술적 측면)
i18n
다국어 컨텐츠를 언어별로 제공할 때는 i18n으로 제공하는 것이 일반적이라고 생각합니다.
각 언어별 json 파일(ko.json, en.json, jp.json과 같은 파일)을 구성하고 i18n 라이브러리를 이용하여 언어별 페이지를 제공하는 방식입니다.
i18n 사용하기로 합시다! 하고 끝나는 것이 아니고, 여기에 줄 언어 파일을 어떻게 관리할 것인지에 대한 고민도 함께 수행되어야 합니다.
[ 어떻게 언어 파일을 관리할 것인가?! ]
저는 방식을 고려할 때 정해져있던 요구사항이 있었습니다
요구사항1. url이 바뀌지 않게 해주세요.
요구사항2. 언어별로 하나의 파일로 언어 파일을 관리해주세요. (나중에 QA 맡길 때 하나의 파일만 전달해줄 수 있도록)
1. 구글 스프레드 시트를 이용하는 방법
https://hanyunseong-log.dev/post/nextjs-i18n
요구사항2에서 엑셀 파일로 관리하길 원치 않았기에 선택되지 못한 방식이지만, 저는 관리 측면에서 좋은 방법이라고 생각합니다.
2. document에서 lang 속성 변경하기
i18n을 사용하면 html에 존재하는 lang 속성이 자동으로 변경됩니다.
요구사항에서 url이 바뀌지 않길 원했기에 documnet에서 직접 lang 속성 값을 변경하는 방식을 고려는 해보았으나, 원하는 시점에 원하는 값을 넣어주는 데 어려움이 있었습니다.
따라서 선택되지 않은 방법입니다
i18n을 사용하면 url이 https://나의주소/ko, https://나의주소/ko 형태로 자동으로 바뀝니다.
url에서 데이터를 꺼내오는 로직이 프로젝트 내에 이미 존재하고 있었으므로 url 이 바뀌는 것은 어떤 오류를 일으킬지 모른다는 이슈로 요구사항1이 생겨났었습니다.
하지만 프로젝트 내에서 Next에서 제공하는 메소드와 훅으로 url에서 올바르게 데이터를 꺼내오고 주입했다면 문제가 생길 가능성이 없으므로 요구사항1은 제거되었습니다.
[그래서 어떻게 적용했다는건가요?]
1. 처리 방식
- next-i18n 사용
- 언어별로 하나의 JSON 파일을 만들어 프론트 코드 내에서 관리
- locale 이용하는 방식 채택
- WHY?
- 공식문서에서 권장하는 방식
- 기기언어가 기본적으로 바로 적용됨.
- html에 lang 정보가 정확하게 들어감.
- 기존에 시도했던 '브라우저 기본 설정 언어를 서버 요청에서 가져오는 방법'(Accept-Language)으로는 404, _error 페이지에서 값을 가져올수 없었음.
2. json 구조 및 네이밍 형식
// public/locales/ko
{
"signUp" : {
"welcome-user": "안녕하세요 {{nickname}}님!"
},
` "myPage" : {
"sign-out": "로그아웃",
}
}
// public/locales/en
{
"signUp" : {
"welcome-user": "Hello {{nickname}}!"
},
` "myPage" : {
"sign-out": "Sign out",
}
}
- key값은 모든 언어에서 동일하게 저장해야 한다.
- 페이지별로 대분류를 나눈다. ➝ Camel Case
- ex) signUp, myPage
- 공통된 텍스트여도 다른 페이지이면 따로 관리한다.
- 단, "preset", "error", "time", "unit" 내 데이터는 여러 페이지에서 사용될 수 있다.
- 다국어 '영어' value값을 key값으로 설정한다.
- 문장이 긴 경우엔 ➝ 요약된 텍스트로 key값을 설정할 수 있다.
- 두 문장으로 이루어진 경우엔 ➝ 기본적으로 첫 문장을 key로 설정한다.
- 다만, 첫 문장이 주된 내용이 아닌 경우엔 두 번째 문장을 key로 설정할 수 있다.
- Kebab Case
- ex) "hello-nice-to-meet-you"
- 엔터를 넣어줘야 할 때 : \n
- ex) "hello": "안녕하세요\n반갑습니다"
- 텍스트 중간에 다른 색상이 들어가야할 때 : __텍스트__
- ex) "hello": "안녕하세요 제 이름은 __고솔미__입니다"
- 해당 방식을 적용하려면 컴포넌트 내 로직 사용이 필요함 ➝ util로 분리할 예정해서 업데이트 예정!
//예시
const parseStringWithJSX = (str: string) => {
return str.split('__').map((part, index) => {
if (index % 2 === 0) {
return part;
} else {
return (
// 컬러가 들어가는 부분
<TitleText key={part} color={Colors.Primary600}>
{part}
</TitleText>
);
}
});
};```
3. 세팅 방법
- next-i18n 설치
pnpm i next-i18next
- next-i18next.config.js 파일 생성 후 next.config.js에 import
- - defaultLocale 정보 등록
- - 지원가능한 언어 정보를 등록
- _app.tsx 에서 appWithTranslation 으로 감싸준다.
export default appWithTranslation(MyApp);
- public/locales/위치에 언어별 폴더를 제작한다.
- - 폴더 네이밍을 지켜줘야 함.
- - ex) public/locales/en폴더 내 'common.json'파일(하나의 언어는 하나의 파일에서 관리)을 만든다.
4. 사용방법
export const getStaticProps = async (context: GetServerSidePropsContext) => {
return {
props: {
...(await serverSideTranslations(context.locale ?? 'ko', ['common'])),
},
};
};
const { t } = useTranslation('common');
// 사용예시
const name = "Marisol"
{t('common:signUp:welcome-user', { nickname: name })}
{t('common:myPage:welcome-user', { nickname: name })}
//json파일 내 데이터 (예시: 변수를 넣어줘야하는 경우)
{
"signUp" : {
"welcome-user": "안녕하세요 {{nickname}}님!"
}
}
5. 네이티브 적용 (웹뷰 + 네이티브)
- 프로젝트 설정 변경
- - Localizations 항목 생성 후 언어 추가

- Localizable 파일 생성
- - 최상단에서 new file ➝ String Catalog 형식 ➝ save as "Localizable"
- - 좌측 목록에 지원하고자 하는 언어 추가
- - 기본적으로 ios 배포를 위해 필요한 다국어 데이터 넣어주기
- : 자동생성된 key값들에 대해 번역을 진행하고 review completed 처리 필요
- : 네이티브와 무관한 다국어 데이터는 이곳에서 추가적인 관리 불필요
- - 프로젝트 info내 Localizations에 다국어 정보가 정확하게 들어가있는지 확인 (하단 사진 참고)

7. 참고링크
[Devrank] NEXT.JS에서 i18n 적용해보기
next.js에 국제화(i18n) 끼얹기
velog.io
Next.js로 다국어(i18n) 제공하기
Next.js로 다국어를 적용하면서 공부하고 고민했던 흔적들에 대해서 설명합니다.
velog.io
📃 프론트엔드 인터뷰 문제 답해보기 #2 DOC TYPE과 다국어 콘텐츠
DOCTYPE은 무엇이며 다국어 처리는 어떻게 해야하는가?
velog.io
7. 에러사항
vercel로 배포하고 있다면 하나의 설정을 추가적으로 하지 않는다면 간헐적으로 다국어를 제대로 적용시키지 못하는 문제가 있을 수 있다.
/** @type {import('next-i18next').UserConfig} */
const path = require('path'); //<-여기. path를 알아볼 수 있도록 지정해줘야 한다. 원래는 자동적으로 폴더 규칙에 따라 언어 파일을 위치시키면 알아서 경로를 찾는데, vercel 배포시 명시가 필요하다..!
module.exports = {
serializeConfig: false,
i18n: {
defaultLocale: 'en',
locales: ['ko', 'en'],
},
localePath: path.resolve('./public/locales'), //여기
preload: ['ko', 'en'],
};
다국어 작업을 혼자 처리했어서 다른 팀원분들께서 히스토리를 모르시더라도 사용할 수 있도록 문서화 작업까지 한 것이 좋은 경험이 되었던 것 같다! 어떻게 해야 다른 사람들이 더 쉽게 이해하고 쓸 수 있을까에 대한 고민을 많이 할 수 있었다ㅎㅎ
다양한 세팅 방법과 파일 관리 방법이 존재하는데, 그 중에서 현 상황에 가장 적합한 방법은 무엇인가에 대한 고민도 깊게 해보았다. 어떤 기능을 추가할 때는 멀리 보고 계획을 세우는 것이 중요한 것 같다!