본문 바로가기

개발/Front-end

[이슈리포트] i18n과 라우팅 변경하기

i18n, internaionalization의 i와 n의 글자수가 18자이기 때문에 i18n인 이 엄청난 공대생 감성의 국제화는 복잡한 이름에 비해서는 다국어를 지원하는 웹 페이지에서 유용하게 사용될 수 있다. 웹 페이지를 사용하는 locale 기반으로 그에 맞는 언어를 설정해줄 수 있기 때문이다.

 

다른 방법도 있겠지만 i18n을 사용하지 않을 경우에 페이지에서 국제화를 위해서는 다음과 같이 비교적 비효율적으로 코드를 작성해야 한다.

const Hello: React.FC = () => {
    const hiEn = "hi";
    const hiKo = "안녕";
    
    return (
    	<>
            {locale === "en" ?
            	<div>{hiEn}</div> :
                <div>{hiKo}</div>
            }
        </>
    )
}

브라우저의 locale이 en일 경우에는 영어로 hi, 한국일 경우에는 한국어로 안녕을 하는 컴포넌트 예시이다. 예시이므로 실제로 동작하지 않을 수 있다.

대부분 React에서는 react-i18next를 사용하면 보다 더 간단하게 작성할 수 있다. 물론, 다국어 대응을 위한 json 파일을 설정해주어야 한다. 다음과 같이 hi에 대한 영문과 국문 파일을 en.json과 ko.json으로 작성한다.

// en.json
{
    "hi": "hi"
}

// ko.json
{
    "hi": "안녕"
}

 

그리고 앞서 작성한 컴포넌트를 다음과 같이 수정한다.

const Hello: React.FC = () => {
    const { t } = useTranslation();
    
    return (
    	<div>{t("hi")}</div>
    )
}

조건문도 필요없이 react-i18next에서 지원하는 hook인 useTranslation을 사용하여 다국어 처리가 끝나게 된다.(물론 react-i18next 또는 next-i18next와 같은 라이브러리는 별도의 설정을 필요로 한다.)

 

이렇게 국제화가 적용되고 나면 페이지의 url이 locale에 따라 다르게 설정된다. 페이지의 url을 hello.com이라고 할 때, 영문(en)일 경우에는 그대로 hello.com이 되고 국문(ko)일 경우에는 hello.com/ko가 된다.

 

이제부터가 본론이다. 프로젝트를 진행하던 중 국제화가 뒤늦게 적용되었고, 그로 인해 기존 로직을 수정해야 하는 문제 상황이다.

기존 홈 경로(/)로 가는 로직은 router를 사용하여 다음과 같이 작성되어 있었다.

router.push("/");

그렇지만 국제화가 적용된 이후 locale이 ko일 경우에는 이 로직이 제대로 동작하지 않는 것이다! 그로 인해 다음과 같이 수정해야 했다.

if(locale === "en") {
    router.push("/", "/", { locale: "en" });
else {
    router.push("/", "/", { locale: "ko" });
}

router에 locale 값을 설정해주어야 했다. 이렇게 작성하고 나니 원하는대로 제대로 동작하는 것을 확인할 수 있었다. 문제가 locale이 아닐 수도 있으니 한 번 더 확인해봐야 하겠지만, 우선 시간이 없어서 급한대로 작성했는데 문제가 해결되었다.

지금 이 글을 작성하면서 생각해보니 굳이 locale값에 따라서 조건문을 거는 것보다 차라리 state를 하나 추가하고 locale 값을 할당해두고 하나의 구문으로 사용하는 것이 더 좋아보인다는 생각이 들었다. 내일 아침에 한 번 리팩토링을 적용해보아야겠다.

 

내용을 정정한다.

라우팅 경로가 잘 동작하지 않은 이유는 locale을 인자로 전달해주었기 때문이 아니었다. next/router에서는 특별히 locale을 지정해주지 않는다면 기본 locale인 defaultLocale 기반의 경로로 이동해준다. 즉, 특별한 경우에서 내가 현재 영문으로 페이지를 보고 있는데 국문 페이지로 이동해야하는 경우가 아니라면 locale을 옵션으로 줄 필요가 없는 것이다.

 

그렇다면 무엇이 문제였는가. 문제가 되는 상황은 최초로 서비스의 로그인했을 때, 회원가입을 위해 프로필을 입력하는 화면으로 이동되었어야 했는데 그 로직이 빠져있는 것이 문제였다. 작성된 로직에서는 로그인을 했다 하더라도 회원 등록이 되어 있지 않다면 정상적으로 로그인이 되지 않는다. 프로필 등록을 통해 회원 가입을 해주는 작업이 우선적으로 실행되어야 했다. 하지만 해당 로직을 간과했기 때문에 당연히 회원 가입이 되어도 로그인이 되지 않고 계속 홈 화면으로만 넘어가지는 것이었다. 

 

정정하자면, i18n을 적용하고 라우팅을 할 때 옵션으로 locale을 주지 않아서 제대로 동작하지 않은 것이 아니라 필요한 로직을 구현하지 않았기 때문에 라우팅이 제대로 동작하지 않은 것이었다. 로그인 로직을 제대로 이해하지 못했기 때문에 발생한 이슈였다.

 


 

i18n을 사용한 국제화 작업은 설정하기 귀찮고(특히 Next.js에서 사용할 경우), 사용되는 요소들을 일일히 찾아서 json 파일로 만들어주어야 하고, 또 이런 라우팅과 같은 경우에 대해서 대응해줘야 할 수도 있다.(아직 이 부분이 문제인지 정확히 파악하지는 못했다. 찾게 되면 추후에 포스팅하리라.) 그렇지만 코드 내에서 별도의 조건문 없이 locale에 따라서 자동으로 번역된 컨텐츠를 표시할 수 있다는 점은 정말 편리하다. 특히 Next.js에서와 같이 server side에서 locale을 확인할 수 있는 경우에는 더더욱.

항상 이런 라이브러리들을 사용할 때마다 본질인 코드에서 더 멀어지는 것 같은 느낌이 들지만, 이 또한 trade-off라고 생각하고 있다.

 

최근에 했던 뻘짓을 공유하며, 만약 이런 분들이 있으시다면 같은 실수를 겪지 않으시길.

i18n을 사용한 국제화는 굉장히 편리하다. 단, 설계 단계에서 미리 페이지의 어떤 요소들이 국제화에 해당하는지 알아두면 작업이 더 용이하다. 이미 작성된 페이지에 대해서 적용할 경우 단순 노가다 작업이 조금 필요로 한다.

반응형