도움말 센터

i18next를 사용한 React 현지화

전 세계 사용자를 위한 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는 컴포넌트 번역을 위해 프로그래밍 방식 액세스를 위한 useTranslation 훅과 JSX가 포함된 리치 텍스트를 위한 Trans 컴포넌트라는 두 가지 주요 API를 제공합니다.

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를 사용한 서버 사이드 렌더링

앱 라우터를 사용하는 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 명령줄 인터페이스를 실행하여 번역하세요
  3. AI가 모든 대상 언어에 대해 문맥상 정확한 번역을 생성합니다
  4. 번역된 JSON 파일을 locales/ 디렉토리에 넣고 배포하세요

ai-l10n 명령줄 인터페이스로 번역 자동화

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 기반 번역의 힘을 결합하여 어떤 언어로든 앱을 빠르게 출시하세요.