(React) Next.js 로 만든 프로젝트에 다국어 설정 끼얹기

cleopatra·2022년 2월 22일
5
post-thumbnail
post-custom-banner

앗! Next.js 다국어 설정 타이어보다 쉽다!



알아두기 : next-i18next 동작방식

기본적으로 URL 을 통해 적용된다.
기존 Vue나 CRA 프로젝트로는 이렇게 안하고 store에 변수 저장해놓고 어쩌고... 방식에 익숙해서 처음엔 이렇게 하기 싫었다.

근데 일단 하고 나니까 쉬워서 괜찮아졌다 ^.^ 인간은 적응의 동물!

🌐 URL 방식으로 동작해요

hostname 과 path 사이에 언어가 들어간다. 이런 식.

company 라는 페이지를 영문으로 보고 싶으면 위와 같이 접근하면 되는 식이다.
물론 한글로 보려면 localhost:3000/ko/company 이렇게 접속하면 된다.

만약 언어 설정 없이 localhost:3000/company 로 접근한다면?
기본 값으로 설정된 언어가 자동으로 적용 된다.

이렇게요



그럼 이렇게 쉬운 언어설정

레쯔고🛫

1. i18n 설치

npm install --save next-i18next

2. 폴더 만들기

public 경로 아래에 locales 폴더를 만들고 제공할 언어 별로 또 다시 폴더를 만든다.

.
└── public
    └── locales
        ├── ko
        |   └── common.json
        └── en
            └── common.json

common.json 은 공통으로 사용하는 문구를 관리하며, 동일 경로에 페이지 별로 문구들을 묶어놓을 수도 있다.

💌 이전에 프로젝트를 해보니까 이렇게 페이지 별로 관리하는 게 좋다는 생각. 여러명이서 작업하는 프로젝트의 경우 매번 conflict 나는 것도 문제고, 불필요한 문구를 제거할 때도 힘들다.

그러니까 페이지 별로 분리하자면 이런 식.

기본 구조는 이렇고, 물론 변경 가능하다.
단, 구조를 변경 했을 경우 다음에 설정할 config 파일에서 localePath localeStructure 를 설정해주어야 함.

3. 이제 설정 파일을 만들자

폴더를 만들었으니 이게 읽히도록 하자.
프로젝트 루트에 next-i18next.config.js 파일을 만들고 다음과 같이 내용을 적는다.

module.exports = {
  i18n: {
    defaultLocale: 'ko',
    locales: ['ko', 'en'],
  },
};

그리고 위에서 기본 경로가 아닌 다른 경로에 언어 파일을 배치한 경우 아래처럼 추가 설정을 해주면 된다.

const path = require('path');

module.exports = {
  i18n: {
    defaultLocale: 'ko',
    locales: ['ko', 'en'],
  },
  localePath: path.resolve('./my/custom/path'), // 요렇게
};

더 많은 옵션들이 있다.

repo에서 확인하기

4. next.js 가 다국어 설정을 사용하도록 하자

next.config.js 파일을 열어서 i18n 을 사용하도록 설정한다.

const { i18n } = require('./next-i18next.config');

module.exports = {
  i18n,
};

여기서 잠깐! 🍒
만약 내 프로젝트가 webpack 설정을 쓰느라 next.config.js가 좀 복잡하다?

이렇게 하면 됩니다. (주석참조)

/** @type {import('next').NextConfig} */
const path = require('path');

// 똑같이 import 해서 
const { i18n } = require('./next-i18next.config');

const nextConfig = {
  reactStrictMode: true,
  webpack(config) {
    config.resolve.alias = {
      ...config.resolve.alias,
      components: path.resolve(__dirname, 'components/'),
      styled: path.resolve(__dirname, 'styled/'),
      utils: path.resolve(__dirname, 'utils/'),
    }
    return config;
  },
  i18n, // 요기에 넣어주면 끝! 
};

module.exports = nextConfig;

5. App 이 번역 기능을 사용하도록 하자

pages/_app.tsx 파일을 열어 다음과 같이 수정한다.

import { appWithTranslation } from 'next-i18next';

const MyApp = ({ Component, pageProps }) => <Component {...pageProps} />;

export default appWithTranslation(MyApp);

사실상 가운데 과정은 프로젝트 별로 다를 수 있고,

🍋 중요한 것은 export default 로 내보내는 MyApp 이라는 root component 가 appWithTranslation() 으로 감싸져야 한다는 것이다.

서버 사이드 렌더링은 사용하지 않았다.


6. 이제 페이지에서 사용하자

사용법은 짱 쉽다.

  1. useTranslation 을 import한다.
  2. Component 안에서 useTranslation() hook을 사용해서 t 라는 API 를 받는다.
  3. 사용한다.
import { useTranslation } from 'next-i18next';

export const Footer = () => {
  // json 파일 명. common 또는 footer 같은거
  const { t } = useTranslation('footer'); 

  return (
    <footer>
      {/* json 파일 안에 있는 key 값 */}
      <p>{t('description')}</p>
    </footer>
  );
};

여기 useTransaltion('footer')footer 는 앞에서 만든 json 파일명이다.

t('description')description 은 json 파일 안에 있는 key값이다.

(🛑) 끝일 줄 알았는데 안 될 때

각 페이지 코드에 getStaticProps 를 만들어주어야 한다.
이 함수는 Next.js 내용이라 정확히 알지는 못하지만 빌드 할 때 실행되는 코드라고 한다.

props 의 기본 값을 전달하기 위해 페이지에 아래 코드를 넣어주자.

@/pages/index.tsx

// ... 
// 위에 앱 코드가 막 있으면 그 아래에

export const getStaticProps = async ({ locale }) => ({
  props: {
    // common 은 위 locales/ko 아래에 만든 json 파일 명이다. 다른 파일을 사용한다면 바꿔주자.
    ...(await serverSideTranslations(locale, ["common"])),
  },
});

이렇게 해야 i18n 에 기본 언어 값이 적용되어 다국어 설정이 된다.
그리고 이건 pages 내의 모든 페이지 index.tsx 파일에 들어가야 하는 듯..

아래 코드를 참조하세요.

// REACT
import { NextPage } from 'next';
import { serverSideTranslations } from "next-i18next/serverSideTranslations";

const MySample: NextPage = () => {
  return (
    <div className="mysample">
    </div>
  )
};

export const getStaticProps = async ({ locale }) => ({
  props: {
    ...(await serverSideTranslations(locale, ["common"])),
  },
});

export default MySample;

profile
안녕나는클레오파트라세상에서제일가는포테이토칩
post-custom-banner

10개의 댓글

comment-user-thumbnail
2022년 7월 21일

안녕하세요 좋은 글 잘 보았습니다 한가지 궁금한 부분이 있는데
혹시 영문으로 locale을 변경한 상태에서 새로고침을 하는경우 404 에러가 발생하는 경우가 없으신가요??
예를들어 어떠한 유저가 직접 페이지 URL로 접속을 해서 localhost:3000/en/test 라는 주소로 들어오는 경우
next.js가 리소스를 찾는 경로에 /en이 붙어서 404 에러가 발생하는 경우가 있어 비슷한 현상이 없으신지... 질문드립니다

1개의 답글
comment-user-thumbnail
2022년 8월 27일

안녕하세요ㅎㅎ혹시 저기 코드 적힌 부분은 어떻게 만드는 거예요..?

1개의 답글
comment-user-thumbnail
2022년 9월 5일

혹시 getStaticProps를 해주는 이유와 사용 안했을 경우에 어떤 부분이 제대로 동작하지 않았는지 알 수 있을까요?

1개의 답글
comment-user-thumbnail
2023년 2월 6일

export const getStaticProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ["landing"])),
},
});

이것을 추가하면

Initial locale argument was not passed into serverSideTranslations라는 에러가 나는데, 왜이러는지 질문드리고 싶습니다 ㅜㅜ

1개의 답글