[Next] next-export-i18n 사용 시 lang 쿼리 파라미터 자동으로 붙이기

profile
마릴린벅시
2022. 11. 9. 20:54프론트엔드

환경

  • react 18 사용
  • nextJS 사용
  • 번역 기능이 필요하여 next-export-i18n 사용

 

문제

보통 nextJS를 사용하는 경우 국제화 기능(다중 언어 지원)을 위해 next-i18next 라이브러리를 사용할 것이다.

문제는 이 라이브러리를 쓸 경우 빌드 시 아래 명령어를 사용할 수 없다. export를 지원하지 않는다.

"build": "next build && next export"

그래서 찾게 된 것이 export를 지원하는 next-export-i18n 라이브러리이다. 이 라이브러리의 문제점은, 현재 웹페이지에 보여줄 언어로

무엇을 사용할지를 판단할 때 url에 붙은 lang 쿼리파라미터로 판단한다. 즉 웹사이트 내의 모든 페이지 이동 시 lang=en 과 같은 쿼리 파라미터를 붙여줘야 하는 것이다.

그럼 router.push를 할 때마다, href에 경로를 입력할 때마다 {lang : en} 을 입력해줘야 한다는 건데.. 이건 좀 아닌듯 싶었다.

기존에 작성한 모든 페이지 이동 코드를 찾아서 수정해줘야 함은 물론, 앞으로 작성하는 코드에도 쿼리파라미터를 입력해줘야 하는데

새로운 개발자가 왔을 때 & 동료 개발자가 이 사실을 모를 때 & 알고 있지만 쿼리 붙이는걸 깜빡했을 때 등등의 상황에서 반드시 문제가 생길 것이다.. 그리고 자동화되지 않고 수기로 매번 작성해줘야 한다는게 가장 거슬렸다.

해결

가장 상위 컴포넌트인 _app.tsx에서 route가 변경될 때마다 useEffect에서 url을 replace해주는 방식으로 해결했다.

참고로 사용의 편의를 위해서 사용자가 언어 스위치로 언어를 변경할 때마다 localStorage에 해당 언어 정보를 저장해두었다.

그래서 완성한 코드이다.

//in _app.tsx

function MyApp({ Component, pageProps }: AppProps) {

  const router = useRouter()

  useEffect(() => {
    const detectedLng = localStorage.getItem('lang') || 'en'
    const { query } = router //query는 string으로 올 수도 string[]으로 올 수도 있음.
    if (
      query?.lang === detectedLng ||
      query?.lang?.includes(detectedLng) ||
    ) {
      return
    } else {
      router.replace({
        pathname: router.pathname,
        query: { ...query, lang: detectedLng },
      })
    }
  }, [router])
  
  return (
    <QueryClientProvider client={queryClient}>
      <Hydrate state={pageProps.dehydratedState}>
        <Seo />
          <Scripts />
          <GlobalStyle />
          <Layout>
             <Component {...pageProps} />
          </Layout>
      </Hydrate>
    </QueryClientProvider>
  )
}
 

query가 단순 string으로 올 수도 있고 string 배열로 올 수도 있기 때문에 현재 url에 detectedLng(현재 보여져야 할 언어)이 쿼리로 포함되어 있는지 검사할 때 2가지로 검사했다.

query?.lang === detectedLng || query?.lang?.includes(detectedLng)

만약 detectedLng이 이미 쿼리 파라미터에 포함되어 있는 경우 url을 replace하지 않고 return하고

그렇지 않을 경우에는 url에 lang 파라미터를 추가해준다. url에 다른 여러가지 파라미터들이 붙어있을 수도 있으므로

{... query, lang : detectedLng} 으로 기존의 query도 유실되지 않도록 붙여준다.

이제는 페이지를 이동할 때 경로만 입력해줘도 자동으로 lang 파라미터가 붙는다! 해결 ㅎㅎ

 

 

 

반응형