2021. 5. 29. 14:36ㆍDev
기본적으로 nextjs는 i18n을 지원한다.
https://github.com/isaachinman/next-i18next 라이브러리도 있지만 현재(8.3.0) SSR시 문제가 있는 것으로 보인다.
그래서 https://github.com/i18next/react-i18next 라이브러리를 사용해서 구현하였다. 사실 next-18next는 react-i18next의 랩핑 수준의 구현체이므로 크게 다르지 않다.
시작하기
next.config.js 에서 i18n 속성을 정의해 준다.
i18n: {
defaultLocale: 'ko',
locales: ['ko', 'en'],
},
그럼 이제 각 페이지 getStaticProps, getServerSideProps API에서 locale prop으로 접근 가능하다.
export async function getStaticProps(context: GetStaticPropsContext) {
const locale = context.locale
return {
props: {
locale,
},
}
}
컴포넌트에서 locale을 전달 받아서 pages/_app.tsx 컴포넌트에서 i18n Provider를 랩핑해준다.
function App({ Component, pageProps }: AppProps) {
const { locale } = pageProps
const i18n = React.useMemo(() => createI18n({ locale }), [locale])
return (
<I18nextProvider i18n={i18n}>
<Component {...pageProps} />
</I18nextProvider>
)
}
여기서 createI18n은 대략 아래와 같은데 i18n을 초기화 후 인스턴스를 넘겨주는 형태이다. 참고
import i18n, { i18n as I18n } from 'i18next'
import { initReactI18next } from 'react-i18next'
import languages, { lngs } from './languages'
type Props = {
locale: string
}
const { en, ko } = languages
const createI18n = ({ locale }: Props): I18n => {
i18n.use(initReactI18next).init({
resources: { en, ko },
lng: locale,
fallbackLng: lngs[0],
interpolation: {
escapeValue: false,
},
})
return i18n
}
export default createI18n
페이지 컴포넌트에서 아래와 같이 사용하면된다.
import type { GetStaticPropsContext } from 'next'
import { useTranslation } from 'react-i18next'
export async function getStaticProps(context: GetStaticPropsContext) {
const locale = context.locale
return {
props: { locale },
}
}
export default function Home() {
const { t } = useTranslation() // default ns 'common'
return (
<div>
<div>{t('hello')}</div>
</div>
)
}
getStaticProps가 전달해준 locale prop은 pages/_app.tsx 컴포넌트에서 사용하게 된다.
코드를 살펴보면 getStaticProps(혹은 getServerSideProps) API에서 전달하는 props은 pages/_app.tsx 컴포넌트에서 사용한다는 느낌이 직관적이지 않다. 그래서 흐름을 이해하는데 다소 어려웠다. 때문에 공통적으로 페이지 컴포넌트에 locale을 주입해 줄 수 있도록 구현할 수 있는 부분을 찾아보았고 아래와 같다.
pages/_app.tsx
import type { AppProps, AppContext } from 'next/app'
function App({ Component, pageProps, locale }: AppProps & { locale: string }) {
return (
<I18nextProvider i18n={i18n}>
<Component {...pageProps} />
</I18nextProvider>
)
}
App.getInitialProps = async ({ ctx }: AppContext) => {
const { locale } = ctx
return { locale }
}
문제는 페이지 최적화 기능이 opt out 되면서 모든 페이지가 SSR로 작동한다. 빌드시 경고 문구도 볼 수 있다.
https://nextjs.org/docs/messages/opt-out-auto-static-optimization
트레이드 오프를 생각해서 구현할 필요가 있다.
국제화 빌드 과정
getStaticProps API를 사용하면 빌드타임에 locale을 주입하고 각 지원 언어별 html 파일들을 생성해 정적페이지를 만든다.
getServerSideProps 혹은 App.getInitialProps API를 사용하면 서버에서 런타임으로 locale을 주입해주고 html을 동적 생성한다.
귀찮지만 각각의 페이지 컴포넌트에서 locale을 주입해주는 방식이 최적화할 수 있으므로 추천한다.
'Dev' 카테고리의 다른 글
Next.js meta 태그와 script 태그 다루기 (0) | 2021.06.17 |
---|---|
JWT cookie vs localStorage (0) | 2021.06.01 |
amplify nextjs ssr (0) | 2021.05.02 |
redux saga eventChannel에 관하여 (1) | 2020.07.29 |
drag and drop(feat. react) (0) | 2020.02.14 |