한국어

Next.js 애플리케이션에서 원활한 국제화(i18n)를 구현하여 글로벌 사용자에게 다가가는 방법을 알아보세요. 라우팅, 콘텐츠 번역 및 모범 사례를 다룹니다.

Next.js 국제화: 글로벌 사용자를 위한 다국어 앱 구축하기

오늘날과 같이 서로 연결된 세상에서, 글로벌 사용자를 만족시키는 애플리케이션을 구축하는 것은 더 이상 사치가 아닌 필수입니다. 강력한 React 프레임워크인 Next.js는 국제화(i18n) 구현을 위한 견고한 기능을 제공하여, 전 세계 사용자에게 현지화된 경험을 제공하는 다국어 애플리케이션을 만들 수 있도록 지원합니다. 이 종합 가이드는 국제화된 Next.js 애플리케이션을 구축하기 위한 필수 개념, 기술 및 모범 사례를 안내합니다.

국제화(Internationalization)와 현지화(Localization)의 이해

Next.js i18n의 세부 사항을 살펴보기 전에 주요 용어를 명확히 해보겠습니다.

본질적으로 i18n은 애플리케이션의 현지화를 준비하는 과정입니다. 언어 종속적인 요소를 핵심 코드에서 분리함으로써, 다양한 시장을 위해 애플리케이션을 더 쉽게 현지화할 수 있습니다.

Next.js에서 국제화를 구현해야 하는 이유

Next.js 애플리케이션에 i18n을 구현하면 다음과 같은 수많은 이점이 있습니다.

Next.js i18n 기능 및 설정

Next.js는 라우팅 및 콘텐츠 관리 기능을 통해 i18n을 기본적으로 지원합니다. 다음은 주요 기능에 대한 설명입니다.

1. next.config.js에서 i18n 설정하기

i18n의 핵심 설정은 next.config.js 파일에 있습니다. 다음은 예시입니다.


/** @type {import('next').NextConfig} */
const nextConfig = {
  i18n: {
    locales: ['en', 'es', 'fr'], // 지원되는 로케일(언어 코드) 배열
    defaultLocale: 'en', // 사용할 기본 로케일
    localeDetection: true, // 브라우저 설정에 따른 자동 로케일 감지 활성화/비활성화 (선택 사항)
    //  domains: [
    //  {
    //    domain: 'example.com',
    //    defaultLocale: 'en',
    //  },
    //  {
    //    domain: 'example.es',
    //    defaultLocale: 'es',
    //  },
    //  ],
  },
}

module.exports = nextConfig;

설명:

2. 로케일 접두사를 사용한 라우팅

Next.js는 자동으로 경로에 로케일 접두사를 붙입니다. 예를 들어, /about 페이지가 있고 로케일이 'es'(스페인어)인 경우 URL은 /es/about이 됩니다. 이를 통해 페이지의 다른 언어 버전을 제공하고 검색 엔진이 각 로케일에 대한 콘텐츠를 인덱싱할 수 있게 합니다. 프레임워크가 리디렉션과 라우팅을 자동으로 처리합니다.

3. useRouter 훅 활용하기

next/routeruseRouter 훅은 현재 로케일 및 기타 라우팅 정보에 대한 접근을 제공합니다.


import { useRouter } from 'next/router';

function MyComponent() {
  const router = useRouter();
  const { locale, locales, defaultLocale } = router;

  return (
    

Current locale: {locale}

Available locales: {locales.join(', ')}

Default locale: {defaultLocale}

); } export default MyComponent;

router 객체는 다음과 같은 주요 속성을 제공합니다.

콘텐츠 번역 전략

Next.js 애플리케이션을 i18n용으로 설정한 후에는 콘텐츠 번역 전략을 구현해야 합니다. 다음은 몇 가지 인기 있는 접근 방식입니다.

1. 전용 번역 관리 시스템(TMS) 사용하기

많은 언어를 다루는 대규모 프로젝트의 경우 TMS 사용을 적극 권장합니다. 인기 있는 옵션은 다음과 같습니다.

장점:

2. JSON 번역 파일 생성하기

소규모 프로젝트의 경우 JSON 파일을 사용하여 번역을 저장하는 것이 간단하고 효과적인 방법입니다.

예시 디렉토리 구조:


/src
├── locales
│   ├── en.json
│   └── es.json
├── components
│   └── MyComponent.js
└── pages
    └── index.js

예시 en.json:


{
  "greeting": "Hello, world!",
  "welcomeMessage": "Welcome to our website."
}

예시 es.json:


{
  "greeting": "¡Hola, mundo!",
  "welcomeMessage": "Bienvenido a nuestro sitio web."
}

예시 MyComponent.js:


import { useRouter } from 'next/router';
import en from '../locales/en.json';
import es from '../locales/es.json';

function MyComponent() {
  const { locale } = useRouter();
  const t = locale === 'es' ? es : en;

  return (
    

{t.greeting}

{t.welcomeMessage}

); } export default MyComponent;

이 접근 방식은 유연성을 제공하며 소규모 프로젝트에 간단합니다. 일반적으로 업데이트하고 유지 관리하기 쉽습니다.

3. 번역 라이브러리 사용하기

몇몇 JavaScript 라이브러리는 React 컴포넌트 내에서 콘텐츠 번역을 간소화합니다.

next-i18next를 사용한 예시 (설치: npm install next-i18next i18next react-i18next):

i18n 설정 파일을 생성합니다 (예: 루트 디렉토리에 i18n.js).


// i18n.js
import { createServerSideHelpers } from 'next-i18next'
import { i18n } from './next-i18next.config'

export function initI18next(req, res, namespaces = ['common']) {
  const helpers = createServerSideHelpers(
    req, 
    res, 
    i18n, 
    namespaces
  )

  return helpers
}

export { appWithTranslation } from 'next-i18next'
export { i18n }

next-i18next를 위한 Next.js 설정을 생성합니다.


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

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es', 'fr'],
  },
  // other configuration
}

module.exports = nextConfig

_app.js에 설정과 번역 import를 추가합니다:


import { appWithTranslation } from 'next-i18next';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return ;
}

export default appWithTranslation(MyApp);

폴더를 만들고 번역을 위한 로케일로 채웁니다.


/public
└── locales
    ├── en
    │   └── common.json
    ├── es
    │   └── common.json
    └── fr
        └── common.json

예시 en/common.json:


{
  "greeting": "Hello, world!",
  "welcomeMessage": "Welcome to our website."
}

컴포넌트에서 번역 사용하기:


import { useTranslation } from 'next-i18next';

function MyComponent() {
  const { t } = useTranslation('common');

  return (
    

{t('greeting')}

{t('welcomeMessage')}

); } export default MyComponent;

이 예제는 useTranslation 훅을 사용하여 현재 로케일에 따라 번역을 가져옵니다.

동적 경로 및 정적 사이트 생성(SSG) 처리하기

동적 경로(예: 블로그 포스트, 제품 페이지) 및 정적 사이트 생성(SSG)을 다룰 때 국제화는 더 복잡해집니다.

1. 동적 경로 (예: /blog/[slug])

동적 경로의 경우, 빌드 시점에 getStaticPaths를 사용하여 각 로케일에 대한 올바른 경로를 생성해야 합니다. 이 함수는 Next.js가 미리 렌더링해야 할 경로 배열을 반환합니다.


export async function getStaticPaths() {
  const paths = [];
  const locales = ['en', 'es', 'fr'];
  const posts = await fetchPosts(); // 블로그 포스트 데이터 가져오기

  posts.forEach(post => {
    locales.forEach(locale => {
      paths.push({
        params: {
          slug: post.slug,
        },
        locale,
      });
    });
  });

  return {
    paths,
    fallback: false, // 또는 로딩 상태를 표시하려면 'blocking'
  };
}

export async function getStaticProps({ params, locale }) {
  const post = await getPostBySlug(params.slug, locale);

  return {
    props: {
      post,
    },
  };
}

설명:

2. getStaticProps를 사용한 정적 사이트 생성(SSG)

getStaticProps에서 locale 매개변수를 기반으로 번역된 콘텐츠를 가져올 수 있습니다.


export async function getStaticProps({ params, locale }) {
  // locale과 params를 기반으로 콘텐츠 가져오기
  const { post } = await getPostBySlug(params.slug, locale);

  return {
    props: {
      post,
    },
  };
}

getPostBySlug 함수는 주어진 슬러그와 로케일에 대한 번역된 콘텐츠를 가져와야 하며, 이는 번역 파일, 데이터베이스 또는 CMS에서 검색할 수 있습니다.

3. getServerSideProps를 사용한 서버 사이드 렌더링(SSR)

요청 시에 가져와야 하는 콘텐츠의 경우 getServerSideProps를 사용합니다. 이는 콘텐츠가 자주 변경되거나 각 사용자에 맞게 개인화되는 경우에 유용합니다.


export async function getServerSideProps({ params, locale, req, res }) {
  // locale과 params를 기반으로 데이터 가져오기 (예: 데이터베이스에서)
  const data = await fetchData(params.slug, locale);

  return {
    props: {
      data,
    },
  };
}

Next.js 국제화 모범 사례

다음 모범 사례를 따르면 견고하고 유지보수 가능하며 사용자 친화적인 다국어 애플리케이션을 구축하는 데 도움이 됩니다.

국제화된 웹사이트의 SEO 고려 사항

국제화된 웹사이트를 검색 엔진에 최적화하는 것은 전 세계로부터의 유기적 트래픽을 유도하는 데 필수적입니다. 다음은 몇 가지 주요 SEO 모범 사례입니다.

예제: 간단한 다국어 블로그 구축하기

Next.js를 사용하여 간단한 다국어 블로그 예제를 만들어 보겠습니다. 이는 위에서 논의한 개념을 어떻게 적용하는지에 대한 더 구체적인 예시를 제공할 것입니다.

1. 프로젝트 설정

새 Next.js 프로젝트를 생성합니다:


npx create-next-app my-multi-lang-blog
cd my-multi-lang-blog

2. i18n 설정 (next.config.js)


/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  i18n: {
    locales: ['en', 'es', 'fr'],
    defaultLocale: 'en',
  },
}

module.exports = nextConfig

3. 번역 파일 생성

루트 디렉토리에 locales 폴더를 만들고 다음 JSON 파일을 추가합니다:

locales/en.json:


{
  "title": "Welcome to My Blog",
  "postTitle": "My First Post",
  "postContent": "This is the content of my first blog post."
}

locales/es.json:


{
  "title": "Bienvenido a mi Blog",
  "postTitle": "Mi Primer Post",
  "postContent": "Este es el contenido de mi primer publicación de blog."
}

locales/fr.json:


{
  "title": "Bienvenue sur Mon Blog",
  "postTitle": "Mon Premier Article",
  "postContent": "Ceci est le contenu de mon premier article de blog."
}

4. 블로그 포스트 컴포넌트 생성 (예: components/BlogPost.js)


import { useRouter } from 'next/router';
import en from '../locales/en.json';
import es from '../locales/es.json';
import fr from '../locales/fr.json';

function BlogPost() {
  const router = useRouter();
  const { locale } = router;

  let translations;
  switch (locale) {
    case 'es':
      translations = es;
      break;
    case 'fr':
      translations = fr;
      break;
    default:
      translations = en;
  }

  return (
    

{translations.postTitle}

{translations.postContent}

); } export default BlogPost;

5. 인덱스 페이지 생성 (pages/index.js)


import { useRouter } from 'next/router';
import BlogPost from '../components/BlogPost';
import en from '../locales/en.json';
import es from '../locales/es.json';
import fr from '../locales/fr.json';

function HomePage() {
  const router = useRouter();
  const { locale, locales } = router;

  let translations;
  switch (locale) {
    case 'es':
      translations = es;
      break;
    case 'fr':
      translations = fr;
      break;
    default:
      translations = en;
  }

  return (
    

{translations.title}

{locales.map((l) => ( {l.toUpperCase()} ))}
); } export default HomePage;

이 단순화된 예제는 Next.js 국제화의 기본 원칙을 보여줍니다. 이 기본 프레임워크를 확장하여 동적 경로 및 번역 관리 시스템과의 통합과 같은 더 복잡한 기능을 포함할 수 있습니다. 위의 링크를 Link 컴포넌트로 개선하고 적절한 locale 속성을 추가하는 것을 고려해 보세요.

6. 애플리케이션 실행

다음 명령어로 애플리케이션을 실행합니다:


npm run dev

이제 http://localhost:3000(영어), http://localhost:3000/es(스페인어), http://localhost:3000/fr(프랑스어)에서 블로그에 접속할 수 있습니다. 선택된 로케일에 따라 제목과 블로그 포스트 내용이 번역되어 표시되는 것을 볼 수 있습니다.

결론

Next.js는 웹 애플리케이션에 국제화를 구현하기 위한 포괄적인 기능 세트를 제공합니다. 이 가이드에서 설명한 원칙과 기술을 따르면 전 세계 사용자에게 현지화된 경험을 제공하는 다국어 애플리케이션을 만들 수 있습니다. i18n 전략을 조기에 계획하고, 필요에 맞는 번역 방법을 선택하며, 사용자 경험을 우선시하는 것을 잊지 마십시오. 신중한 계획과 실행을 통해 글로벌 고객과 공감대를 형성하고 새로운 성장 기회를 열 수 있는 애플리케이션을 구축할 수 있습니다. 지속적인 학습, 최신 릴리스 및 모범 사례를 따르는 것은 도구와 기술을 효과적으로 활용하고 있음을 보장합니다.

기술이 발전함에 따라 더 진보된 i18n 기능이 등장할 것으로 예상됩니다. 다양한 문화와 언어 그룹의 사용자에게 다가갈 수 있는 능력은 전 세계 애플리케이션 개발자에게 계속해서 핵심 우선순위가 될 것입니다. 따라서 i18n의 기본을 마스터하는 것은 오늘날의 글로벌 개발 환경에서 당신의 가치를 높이는 귀중한 기술입니다.

Next.js 국제화: 글로벌 사용자를 위한 다국어 앱 구축하기 | MLOG