다국어를 지원하는 페이지를 만들어보자
이번에 회사에서 진행한 프로젝트는 약 100개국, 언어로는 50개 정도 다국어를 지원해야 했습니다. 라이브러리를 사용해 처리를 하는건 처음이다보니 어떤 라이브러리를 써야할지 고민이 되었던 것 같습니다. 다국어 처리를 위한 라이브러리로는 여러 개 있지만 작업하고 있는 환경이 Next.js이다 보니 Next-intl을 사용했습니다.
next-intl – Internationalization (i18n) for Next.js
이전에는 다국어처리를 어떻게 했었나요?
물론 다국어 처리를 안해본건 아닙니다. 그럼 이전에는 라이브러리를 사용하지 않고 다국어처리를 어떻게 했는가 궁금하실수도 있으실텐데요, 엑셀 데이터를 JSON으로 변환해서 key를 사용해서 구현했었습니다.
1. URL의 params 값을 받는다. 이때 params는 language code이다.
2. 해당 국가의 json을 불러와서 매칭되는 value값을 반환한다.문자열 그대로 반환하는 거라면 이 방법도 문제는 없습니다. 하지만 키 값을 직접 작성해야하기 때문에 타입 안정성이 떨어진다는 단점과 동적인 데이터를 처리할때의 불편함이 있었습니다.
만약 사용자가 이메일을 입력한다고 가정해보자구요. 그리고 "입력한 이메일 'test_account@gmail.com'로 인증코드를 전송했습니다." 라는 메세지를 보여줘야한다면 그냥 문자열을 반환하는 방법이라면 코드가 매우 번거로워집니다.
이런 경우에 Next-intl을 사용해 매우 편리하게 작업할 수 있었습니다.🙂
Next-intl 사용하기
번역팀에게 번역 텍스트를 요청하되 <address>{email}</address> 부분은 실시간 데이터가 들어갈 예정이니, 번역할 때 제외하고 번역해달라는 요청사항을 보냅니다.
그리고 동적 데이터가 들어갈 부분에 rich 함수를 사용해 이메일 텍스트는 <span className="text-blue-500">{email}</span> 으로 변환해줘 라는 코드를 작성합니다.
결과적으로 DOM을 렌더링할때 이메일 부분만 파란색으로 나타나도록 구현할 수 있습니다.

이런 기능뿐만 아니라 더 좋은 기능들이 많은데요, 많이 활용하지 못한 것이 아쉽습니다. 이번 프로젝트에 라우팅을 사용해 다국어 처리를 하는 방법과 라우팅을 사용하지 않고 브라우저의 accept-language 값을 확인해서 다국어 처리를 하는 방법 두 가지를 모두 사용했어야 했는데, 구현해야할 시간이 너무 짧아 제대로 학습하지 못하고 사용한 것 같습니다. 그래도 이번 프로젝트를 통해 다국어 처리를 어떤 방식으로 하는지, 라이브러리를 사용했을 때의 장점에 대해서 배우게 된 시간이었습니다.😀
끝난게 끝난게 아닙니다.
저도 모두 끝난 줄 알았습니다. 하지만 프로그램을 실행시켰을 때, 콘솔창에 다음과 같은 에러가 발생했습니다.
Incorrect locale information provided

정확하지 않은 로케일을 받았다는 에러인데요, 모든 국가에서 나타나는 건 아니고 스페인어를 쓰는 라틴아메리카 국가들에서만 발생했습니다.
원인은 es-419 대신 es-LTN을 사용했기 때문입니다. url에서 확인할 수 있는 언어코드가 es-LTN으로 들어오기 때문에 작업상 편리하게 "es-419가 확인되면 es-LTN으로 넘겨줄게!"라는 코드를 작성했는데요 es-LTN은 표준 로케일이 아니기 때문에 에러가 발생하고 있었습니다.
export type Locale = (typeof locales)[number];
export const locales = [
'es-LTN', // es-419로 변경해야 함
'en-US',
'en-GB',
'el',
'de-DE',
'da',
'cs',
'bs',
'bn',
'bg',
'az',
] as const;
export const defaultLocale: Locale = 'en-US';해결
간단하게 문제를 정리해보면 다음과 같습니다.
- locale과 message.json이 다른 경우가 있다.
- locale === "es-419"
- message.json === es-LTN.json
그러면 결론은 다른 국가는 받은 언어코드를 locale과 번역본을 찾는 코드를 동일하게 사용하고, es-LTN의 국가만 locale에 es-419를 전달하면 되는 해결이 됩니다.
export async function getBrowserLocale() {
const serviceLangCode = await getServiceLangCode(); // 언어코드를 받아오는 로직
if (serviceLangCode === 'es-LTN') return 'es-419';
return serviceLangCode;
}
const locale = await getBrowserLocale();브라우저의 언어코드를 가져오는 과정과 라우터에서 언어코드를 가져오는 과정 두 가지 방법을 모두 구현하려고 하다보니 저 스스로도 헷갈리는 부분이 많이 있었던 것 같습니다. 돌아보니 간단한 문제를 너무 어렵게 생각했던 건 아닌가 싶기도 합니다🤔