도움 센터

React i18next를 활용한 현지화

글로벌 사용자를 위한 React 애플리케이션을 구축하려면 강력한 국제화(i18n) 전략이 필요합니다. react-i18next는 검증된 i18next 프레임워크를 기반으로 구축된 가장 인기 있는 React 현지화 라이브러리입니다. 이 가이드는 초기 설정부터 AI 기반 번역을 통한 프로덕션 수준의 자동화까지, React 앱 현지화에 필요한 모든 과정을 안내합니다.

왜 React 현지화에 react-i18next를 선택해야 할까요?

react-i18next는 전 세계 수천 개의 프로덕션 애플리케이션에서 신뢰받는 React 국제화의 사실상 표준입니다. 개발자들이 이 라이브러리를 선택하는 이유는 다음과 같습니다:

  • 훅 기반 API - useTranslation() 훅은 언어 변경 시 자동 리렌더링을 지원하며 깔끔하고 직관적인 React 통합을 제공합니다.
  • 풍부한 생태계 - 언어 감지, HTTP 백엔드, 캐싱 등을 위한 플러그인을 제공합니다. 바퀴를 다시 발명할 필요 없이 기능을 확장하세요.
  • JSON 번역 형식 - 편집, 버전 관리, 번역 도구 및 AI 서비스와의 통합이 쉬운 표준 JSON 파일을 사용합니다.
  • 네임스페이스 지원 - 번역을 논리적 그룹(인증, 대시보드, 오류 등)으로 구성하여 유지보수성을 높이고 지연 로딩을 구현할 수 있습니다.
  • SSR 및 Next.js 지원 - 서버 사이드 렌더링, React 서버 컴포넌트, Next.js 앱 라우터와 원활하게 작동합니다.
  • TypeScript 지원 - 자동 완성을 통해 번역 키에 대한 완전한 타입 안전성을 제공하며, 컴파일 타임에 누락된 키를 잡아냅니다.

설치

react-i18next와 핵심 i18next 라이브러리를 설치하세요:

npm install react-i18next i18next

선택적 플러그인

이 인기 플러그인들은 자동 언어 감지 및 지연 로딩 번역 기능을 통해 i18next 설정을 향상시킵니다:

# Language detector (auto-detects user language)
npm install i18next-browser-languagedetector

# HTTP backend (load translations from server)
npm install i18next-http-backend

권장 프로젝트 구조

잘 구성된 프로젝트 구조는 더 많은 언어를 추가할 때 번역을 유지 관리하기 쉽게 만들어 줍니다:

src/
├── i18n/
│   └── i18n.ts                  ← i18next configuration
├── locales/
│   ├── en/
│   │   └── translation.json     ← English (source)
│   ├── fr/
│   │   └── translation.json     ← French
│   ├── de/
│   │   └── translation.json     ← German
│   ├── ja/
│   │   └── translation.json     ← Japanese
│   └── es/
│       └── translation.json     ← Spanish
├── components/
├── App.tsx
└── index.tsx

번역 JSON 파일 형식

react-i18next는 번역을 위해 중첩된 JSON 파일을 사용합니다. 키는 점 표기법, {{variables}}를 사용한 보간법, 내장된 복수형 처리를 지원합니다:

// locales/en/translation.json
{
  "welcome": {
    "title": "Welcome to our platform",
    "greeting": "Hello, {{name}}!",
    "description": "Explore features and get started."
  },
  "nav": {
    "home": "Home",
    "dashboard": "Dashboard",
    "settings": "Settings",
    "logout": "Log out"
  },
  "cart": {
    "empty": "Your cart is empty",
    "item_one": "{{count}} item in your cart",
    "item_other": "{{count}} items in your cart",
    "checkout": "Proceed to checkout"
  }
}
  • 중첩 키 - 번역을 계층적으로 구성하여(예: welcome.title, nav.home) 구조를 명확하게 만듭니다.
  • 보간법 - 런타임에 삽입되는 동적 값을 위해 {{variableName}} 구문을 사용하세요.
  • 복수형 - 자동 복수형 처리를 위해 _one 및 _other 접미사(또는 복잡한 언어를 위한 _zero, _two, _few, _many)를 추가하세요.
  • 문맥 - 필요한 경우 성별에 따른 번역을 위해 _male, _female 접미사를 사용하세요.

i18next 구성

i18next는 번역을 로드하기 위한 두 가지 주요 접근 방식을 지원합니다: HTTP 백엔드(지연 로딩)와 번들 리소스입니다. 앱의 요구 사항에 따라 선택하세요.

HTTP 백엔드 (대규모 앱 권장)

서버의 JSON 파일에서 필요할 때마다 번역을 로드합니다. 초기 번들 크기를 작게 유지하며, 언어가 많거나 번역 파일이 큰 앱에 이상적입니다:

// src/i18n/i18n.ts
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import HttpBackend from "i18next-http-backend";

i18n
  .use(HttpBackend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",
    supportedLngs: ["en", "fr", "de", "ja", "es"],
    defaultNS: "translation",
    interpolation: {
      escapeValue: false, // React already escapes by default
    },
    backend: {
      loadPath: "/locales/{{lng}}/{{ns}}.json",
    },
    detection: {
      order: ["localStorage", "navigator", "htmlTag"],
      caches: ["localStorage"],
    },
  });

export default i18n;

번들 리소스 (간단한 접근 방식)

번역을 번들로 직접 가져옵니다. 소규모 앱이거나 네트워크 요청 없이 번역을 즉시 사용할 수 있어야 할 때 가장 좋습니다:

// src/i18n/i18n.ts — Bundled approach (no HTTP backend)
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";

import en from "../locales/en/translation.json";
import fr from "../locales/fr/translation.json";
import de from "../locales/de/translation.json";

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",
    supportedLngs: ["en", "fr", "de"],
    defaultNS: "translation",
    interpolation: {
      escapeValue: false,
    },
    resources: {
      en: { translation: en },
      fr: { translation: fr },
      de: { translation: de },
    },
  });

export default i18n;

앱 내 초기화

컴포넌트를 렌더링하기 전에 앱 진입점에서 i18n 구성 파일을 가져오세요. 이렇게 하면 UI가 렌더링되기 전에 번역이 로드됩니다:

// src/index.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./i18n/i18n"; // Initialize i18next before rendering

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

React 컴포넌트 번역하기

react-i18next는 컴포넌트 번역을 위해 두 가지 주요 API를 제공합니다: 프로그래밍 방식 접근을 위한 useTranslation 훅과 JSX를 포함한 서식 있는 텍스트를 위한 Trans 컴포넌트입니다.

useTranslation 훅

useTranslation 훅은 함수형 컴포넌트에서 번역에 접근하는 가장 일반적인 방법입니다. t() 함수를 제공하며 언어 변경 시 자동으로 리렌더링됩니다:

import { useTranslation } from "react-i18next";

function WelcomeBanner() {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t("welcome.title")}</h1>
      <p>{t("welcome.greeting", { name: "Alice" })}</p>
      <p>{t("welcome.description")}</p>
    </div>
  );
}

서식 있는 텍스트를 위한 Trans 컴포넌트

번역에 HTML이나 JSX 요소(굵게, 링크 등)가 포함된 경우 Trans 컴포넌트를 사용하세요. 번역 내에서 React 컴포넌트 트리를 보존합니다:

import { Trans } from "react-i18next";

function RichTextExample() {
  return (
    <p>
      <Trans i18nKey="richText.welcome">
        Welcome to <strong>our platform</strong>.
        Visit your <a href="/dashboard">dashboard</a> to get started.
      </Trans>
    </p>
  );
}

// In the translation file:
// "richText.welcome": "Welcome to <1>our platform</1>. Visit your <3>dashboard</3> to get started."

복수형 처리

i18next는 각 언어의 ICU 복수형 규칙에 따라 복수형을 자동으로 처리합니다. count 매개변수를 전달하면 i18next가 올바른 복수형을 선택합니다:

// In translation JSON:
// "cart.item_one": "{{count}} item in your cart"
// "cart.item_other": "{{count}} items in your cart"

import { useTranslation } from "react-i18next";

function CartSummary({ itemCount }: { itemCount: number }) {
  const { t } = useTranslation();

  return (
    <p>{t("cart.item", { count: itemCount })}</p>
  );
}

// itemCount=0 → "0 items in your cart"
// itemCount=1 → "1 item in your cart"
// itemCount=5 → "5 items in your cart"
  • 영어의 경우 번역 키에 _one 및 _other 접미사를 추가하세요
  • 복잡한 복수형 규칙을 가진 언어(아랍어, 폴란드어, 러시아어 등)의 경우 필요에 따라 _zero, _two, _few, _many 접미사를 추가하세요
  • i18next는 대상 언어의 CLDR 복수형 규칙에 따라 올바른 형식을 자동으로 선택합니다

네임스페이스로 구성하기

네임스페이스를 사용하면 기능이나 도메인별로 번역을 별도의 파일로 분할할 수 있습니다. 이는 유지보수성을 향상시키고 번역 번들의 지연 로딩을 가능하게 합니다:

// src/i18n/i18n.ts
i18n.init({
  defaultNS: "common",
  ns: ["common", "dashboard", "auth", "errors"],
  backend: {
    loadPath: "/locales/{{lng}}/{{ns}}.json",
  },
});

// Usage in components:
import { useTranslation } from "react-i18next";

function DashboardPage() {
  // Load specific namespace
  const { t } = useTranslation("dashboard");

  return <h1>{t("title")}</h1>;
}

function LoginForm() {
  // Load multiple namespaces
  const { t } = useTranslation(["auth", "common"]);

  return (
    <form>
      <h2>{t("auth:login.title")}</h2>
      <button>{t("common:submit")}</button>
    </form>
  );
}

동적 언어 전환

react-i18next를 사용하면 언어 전환이 원활합니다. i18n.changeLanguage()를 호출하면 useTranslation을 사용하는 모든 컴포넌트가 새 언어로 자동 리렌더링됩니다:

import { useTranslation } from "react-i18next";

const LANGUAGES = [
  { code: "en", label: "English" },
  { code: "fr", label: "Français" },
  { code: "de", label: "Deutsch" },
  { code: "ja", label: "日本語" },
  { code: "es", label: "Español" },
];

function LanguageSwitcher() {
  const { i18n } = useTranslation();

  const changeLanguage = (lng: string) => {
    i18n.changeLanguage(lng);
  };

  return (
    <select
      value={i18n.language}
      onChange={(e) => changeLanguage(e.target.value)}
    >
      {LANGUAGES.map(({ code, label }) => (
        <option key={code} value={code}>
          {label}
        </option>
      ))}
    </select>
  );
}

React Suspense 및 지연 로딩

react-i18next는 React Suspense와 통합되어 비동기 번역 로딩을 원활하게 처리합니다. HTTP 백엔드를 사용할 때 Suspense는 번역이 가져와지는 동안 깔끔한 로딩 상태를 제공합니다:

import { Suspense } from "react";
import { useTranslation } from "react-i18next";

// i18next supports React Suspense for async translation loading
function App() {
  return (
    <Suspense fallback={<div>Loading translations...</div>}>
      <MainContent />
    </Suspense>
  );
}

function MainContent() {
  const { t, ready } = useTranslation();

  // With Suspense, 'ready' is always true here
  return <h1>{t("welcome.title")}</h1>;
}

TypeScript 타입 안전 번역 키

i18next는 완전한 TypeScript 통합을 지원합니다. i18next 모듈을 보강하면 모든 번역 키에 대한 자동 완성 및 컴파일 타임 검사를 얻을 수 있어 오타나 누락된 번역을 방지할 수 있습니다:

// src/i18n/types.ts
import "i18next";
import translation from "../locales/en/translation.json";

declare module "i18next" {
  interface CustomTypeOptions {
    defaultNS: "translation";
    resources: {
      translation: typeof translation;
    };
  }
}

// Now t() calls are fully type-safe:
// t("welcome.title")       ✅ Autocomplete works
// t("welcome.greeting")    ✅ Valid key
// t("invalid.key")         ❌ TypeScript error
타입 안전 키는 useTranslation, Trans 컴포넌트 및 모든 i18next API와 함께 작동합니다. 누락되거나 잘못 입력된 키는 IDE에서 TypeScript 오류로 표시됩니다.

Next.js를 이용한 서버 사이드 렌더링

App Router를 사용하는 Next.js 애플리케이션의 경우 서버 및 클라이언트 컴포넌트 모두에서 i18next를 사용할 수 있습니다. 요청 간 상태 공유를 방지하기 위해 서버 측 번역을 위한 별도의 i18next 인스턴스를 만드세요:

// next-i18next.config.js (Next.js App Router)
// For Next.js 13+ with App Router, use next-intl or i18next directly

// src/i18n/server.ts
import { createInstance } from "i18next";
import { initReactI18next } from "react-i18next/initReactI18next";

export async function getServerTranslation(lng: string) {
  const i18nInstance = createInstance();
  await i18nInstance.use(initReactI18next).init({
    lng,
    fallbackLng: "en",
    resources: {
      [lng]: {
        translation: (await import(`../locales/${lng}/translation.json`)).default,
      },
    },
  });
  return i18nInstance;
}

// In a Server Component:
export default async function Page({ params }: { params: { lng: string } }) {
  const i18n = await getServerTranslation(params.lng);
  const t = i18n.t.bind(i18n);

  return <h1>{t("welcome.title")}</h1>;
}
  • 사용자 간 상태 누출을 방지하기 위해 서버에서 요청당 새로운 i18next 인스턴스를 생성하세요
  • 서버 및 클라이언트 렌더링 모두에 동일한 번역 JSON 파일을 사용하세요
  • 복잡한 Next.js 설정의 경우 i18next-resources-to-backend 또는 next-intl을 대안으로 고려하세요

AI로 번역 가속화

react-i18next를 설정하는 것은 절반의 성공일 뿐입니다. 모든 대상 언어에 대해 고품질 번역이 여전히 필요합니다. 수십 개의 JSON 파일을 수동으로 번역하는 것은 느리고 비용이 많이 들며 오류가 발생하기 쉽습니다. AI 기반 번역이 판도를 바꿉니다.

왜 React i18next에 l10n.dev를 사용해야 할까요?

l10n.dev는 개발자 현지화 워크플로우를 위해 특별히 제작되었습니다. JSON 번역 파일을 기본적으로 이해하며 기계가 생성한 것 같지 않은 자연스러운 번역을 제공합니다:

  • 기본 JSON 지원 — translation.json을 업로드하고 완벽하게 포맷된, 즉시 사용 가능한 JSON 파일을 돌려받으세요
  • 문맥 인식 AI — 앱의 도메인을 이해하여 언어 전반에 걸쳐 기술 용어와 브랜드 보이스를 보존합니다
  • 보간법 안전 — {{variables}}, 복수형 접미사(_one, _other), 중첩된 키 구조를 보존합니다
  • 일괄 번역 — 며칠이 아닌 수초 내에 10개 이상의 언어로 동시에 번역하세요
  • CI/CD 통합 — ai-l10n npm 패키지로 빌드 파이프라인의 일부로 번역을 자동화하세요

AI 번역 워크플로우

  1. 영어(또는 기본 언어)로 소스 translation.json을 작성하세요
  2. l10n.dev에 업로드하거나 ai-l10n CLI를 실행하여 번역하세요
  3. AI가 모든 대상 언어에 대해 문맥적으로 정확한 번역을 생성합니다
  4. 번역된 JSON 파일을 locales/ 디렉토리에 넣고 배포하세요

ai-l10n CLI로 번역 자동화

ai-l10n npm 패키지는 AI 번역을 개발 워크플로우에 직접 통합합니다. 명령줄에서 JSON 파일을 번역하세요:

# Install the l10n.dev CLI
npm install ai-l10n

# Translate your JSON files to multiple languages at once
npx ai-l10n translate src/locales/en/translation.json \
  --languages fr,de,ja,es,ko,zh-CN

빌드 통합

번역이 항상 최신 상태를 유지하도록 빌드 파이프라인에 번역 자동화를 추가하세요:

package.json 스크립트

{
  "scripts": {
    "translate": "ai-l10n translate src/locales/en/translation.json --languages fr,de,ja,es,ko --update",
    "pretranslate": "npm run translate",
    "dev": "vite",
    "build": "npm run translate && vite build"
  }
}

Makefile

LANGUAGES = fr,de,ja,es,ko,zh-CN

translate:
	npx ai-l10n translate src/locales/en/translation.json --languages $(LANGUAGES) --update

dev: translate
	npx vite

build: translate
	npx vite build

CI/CD 통합 및 자동화에 대한 자세한 내용은 다음을 참조하세요: 현지화 자동화 가이드

JSON 번역을 위한 VS Code 확장 프로그램

VS Code에서 직접 React i18next JSON 파일을 번역하세요. l10n.dev 확장 프로그램을 사용하면 편집기를 떠나지 않고도 파일을 번역할 수 있습니다:

작동 방식

  1. VS Code 마켓플레이스에서 l10n.dev 확장 프로그램을 설치하세요
  2. 소스 translation.json 파일을 여세요
  3. 마우스 오른쪽 버튼을 클릭하고 'Translate with l10n.dev'를 선택하세요
  4. 대상 언어를 선택하고 즉시 번역된 파일을 받으세요

오늘부터 React 앱 현지화를 시작하세요

이제 react-i18next로 완전히 현지화된 React 애플리케이션을 구축하는 데 필요한 모든 것을 갖추었습니다. i18next의 성숙한 생태계와 AI 기반 번역의 힘을 결합하여 어떤 언어로든 앱을 빠르게 출시하세요.