SEO//14 최소 읽기 시간

React i18n: 2024년 React 국제화 완벽 가이드

Eray Gündoğmuş
공유
목차

React i18n: 2024년 React 국제화 완벽 가이드

전 세계 사용자를 위한 React 앱을 구축하는 것은 이제 선택 사항이 아니라 경쟁력 있는 필수 요건입니다. 유럽, 라틴 아메리카, 아시아 등 새로운 시장에 진출하든, React 국제화(일반적으로 React i18n으로 줄여 씁니다)는 이를 가능하게 하는 토대입니다.

이 가이드는 React i18n이 실제로 무엇을 의미하는지부터 전통적인 설정 방법, 가장 인기 있는 React 지역화 라이브러리 비교, 그리고 better-i18n 같은 현대적인 플랫폼이 개발자 병목 현상을 완전히 없애는 방법까지 모든 것을 다룹니다.


목차

  1. React i18n이란?
  2. React 지역화가 중요한 이유
  3. 핵심 개념: i18n vs l10n vs g11n
  4. 전통적인 방식으로 React i18n 설정하기
  5. 인기 React i18n 라이브러리 비교
  6. react-i18next: 심층 분석
  7. react-intl: 심층 분석
  8. 전통적인 React 지역화의 숨겨진 비용
  9. better-i18n으로 React 국제화를 단순화하는 방법
  10. 코드 예시: 전통적인 방식 vs better-i18n
  11. React i18n 모범 사례
  12. 자주 묻는 질문

React i18n이란? {#what-is-react-i18n}

React i18n은 여러 언어와 지역 설정을 지원하는 방식으로 React 애플리케이션을 설계하고 구축하는 과정을 말합니다. "i18n"이라는 용어는 "internationalization"의 약어입니다. 해당 단어에서 "i"와 "n" 사이에 18개의 문자가 있기 때문입니다.

국제화는 단순한 번역이 아닙니다. 다음 사항들을 포괄합니다.

  • 텍스트 번역 — 사용자의 언어로 UI 문자열 렌더링
  • 날짜 및 시간 형식 — 지역마다 날짜 형식이 다릅니다 (MM/DD/YYYY vs DD/MM/YYYY)
  • 숫자 및 통화 형식 — 소수점 구분 기호로 쉼표 vs 마침표, 통화 기호
  • 복수형 규칙 — 러시아어나 아랍어 등의 언어는 복잡한 복수형을 가집니다
  • 오른쪽에서 왼쪽(RTL) 지원 — 아랍어, 히브리어 등의 언어는 오른쪽에서 왼쪽으로 읽습니다
  • 로케일 인식 정렬 — 알파벳 순서는 로케일마다 다릅니다

React 생태계에서 i18n은 react-i18nextreact-intl 같은 전용 라이브러리, 커스텀 구현, 또는 전체 워크플로우를 코드 변경 없이 처리하는 better-i18n 같은 콘텐츠 플랫폼을 통해 처리됩니다.


React 지역화가 중요한 이유 {#why-react-localization-matters}

React 지역화의 비즈니스 사례는 명확합니다.

  • 소비자의 **72.4%**가 자국어 웹사이트에서 대부분 또는 모든 시간을 보냅니다 (CSA Research)
  • 소비자의 **56.2%**는 가격보다 자국어로 정보를 얻는 능력이 더 중요하다고 말합니다
  • 5개 이상의 언어로 지역화된 앱은 영어 전용 앱보다 최대 3배 더 많은 수익을 창출합니다
  • Google과 기타 검색 엔진은 비영어 쿼리에 대해 지역화된 콘텐츠를 더 높게 순위 매깁니다. 이는 react js 지역화가 SEO에 직접적인 영향을 미친다는 것을 의미합니다

React 기반의 SaaS 제품, 전자 상거래 스토어, 콘텐츠 플랫폼의 경우 지역화를 건너뛰면 상당한 수익을 포기하는 것과 같습니다. React JS 지역화는 시간이 지남에 따라 복리로 증가하는 투자입니다.


핵심 개념: i18n vs l10n vs g11n {#core-concepts}

구현에 들어가기 전에 세 가지 관련 용어를 이해하는 것이 도움이 됩니다.

용어전체 이름의미
i18nInternationalization여러 로케일을 지원하도록 소프트웨어 설계
l10nLocalization특정 로케일에 맞게 소프트웨어 적응 (번역 + 문화적 적응)
g11nGlobalizationi18n과 l10n을 결합한 전체 프로세스

React 개발에서:

  • i18n은 코드에서 수행하는 작업입니다. 인프라 설정
  • l10n은 번역가가 수행하는 작업입니다. 실제 번역된 콘텐츠 작성
  • 목표는 이 두 가지 관심사를 가능한 한 분리하는 것입니다

대부분의 React i18n 문제는 이 두 가지를 혼합하는 데서 발생합니다. 개발자들이 JSON 번역 파일을 관리하고, JSON 파일을 통해 번역가와 조율하며, UI가 변경될 때마다 새 키를 수동으로 추출해야 합니다. better-i18n 같은 현대적인 플랫폼은 이러한 마찰을 완전히 제거하기 위해 존재합니다.


전통적인 방식으로 React i18n 설정하기 {#traditional-setup}

더 나은 접근 방식이 왜 존재하는지 이해하려면 전통적인 React JS i18n 설정을 살펴보는 것이 도움이 됩니다. 대부분의 전통적인 접근 방식은 동일한 패턴을 따릅니다.

1단계: 라이브러리 설치

npm install react-i18next i18next i18next-browser-languagedetector

2단계: 번역 JSON 파일 생성

다음과 같은 폴더 구조를 만듭니다.

src/
  locales/
    en/
      translation.json
    fr/
      translation.json
    de/
      translation.json

각 JSON 파일에는 키-값 쌍이 포함됩니다.

// src/locales/en/translation.json
{
  "welcome": "Welcome to our app",
  "nav": {
    "home": "Home",
    "about": "About",
    "pricing": "Pricing"
  },
  "cta": {
    "signup": "Sign up for free",
    "login": "Log in"
  }
}
// src/locales/fr/translation.json
{
  "welcome": "Bienvenue dans notre application",
  "nav": {
    "home": "Accueil",
    "about": "À propos",
    "pricing": "Tarifs"
  },
  "cta": {
    "signup": "S'inscrire gratuitement",
    "login": "Se connecter"
  }
}

3단계: i18next 구성

// src/i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

import enTranslation from './locales/en/translation.json';
import frTranslation from './locales/fr/translation.json';
import deTranslation from './locales/de/translation.json';

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    resources: {
      en: { translation: enTranslation },
      fr: { translation: frTranslation },
      de: { translation: deTranslation },
    },
    fallbackLng: 'en',
    debug: process.env.NODE_ENV === 'development',
    interpolation: {
      escapeValue: false,
    },
  });

export default i18n;

4단계: 앱 래핑

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './i18n';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

5단계: 컴포넌트에서 번역 사용

// src/components/HeroSection.jsx
import { useTranslation } from 'react-i18next';

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

  return (
    <section>
      <h1>{t('welcome')}</h1>
      <a href="/signup">{t('cta.signup')}</a>
    </section>
  );
}

export default HeroSection;

이 설정은 작동하지만, 앱이 성장함에 따라 상당한 지속적인 비용이 발생합니다.


인기 React i18n 라이브러리 비교 {#libraries-compared}

React 지역화를 위한 몇 가지 성숙한 라이브러리가 있습니다. 가장 널리 사용되는 옵션들을 분석합니다.

react-i18next

GitHub Stars: 9,000+ | 주간 다운로드: 4M+

가장 인기 있는 React i18n 라이브러리입니다. i18next 위에 구축되어 hook(useTranslation), 고차 컴포넌트, 복잡한 번역을 위한 Trans 컴포넌트를 제공합니다.

장점:

  • 방대한 생태계와 커뮤니티
  • 유연한 백엔드 플러그인 (파일, API, CDN에서 번역 로드)
  • 기능별 번역 분리를 위한 네임스페이스 지원
  • 좋은 TypeScript 지원
  • 번역 네임스페이스의 지연 로딩

단점:

  • 장황한 초기 구성
  • JSON 번역 파일의 수동 관리 필요
  • 키 추출은 별도로 수행 필요 (i18next-parser 같은 도구 사용)
  • 번역가가 JSON 파일로 작업해야 함. 번역가 친화적이지 않음
  • 번역 관리 UI 미내장

react-intl (FormatJS)

GitHub Stars: 14,000+ | 주간 다운로드: 2.5M+

FormatJS 제품군의 일부인 react-intl은 Yahoo/Formatjs가 유지 관리하며 ICU 메시지 형식 표준을 따릅니다.

장점:

  • 업계 표준 ICU 메시지 형식
  • 탁월한 복수형 및 성별 처리
  • 내장 날짜, 시간, 숫자 형식
  • 대형 엔터프라이즈 애플리케이션에 적합
  • 강력한 TypeScript 타입

단점:

  • react-i18next보다 가파른 학습 곡선
  • 더 장황한 API (<FormattedMessage>로 모든 것을 래핑)
  • ICU 구문은 번역가에게 복잡할 수 있음
  • 여전히 번역 파일을 수동으로 관리해야 함
  • 번역 관리 미내장

Lingui

GitHub Stars: 4,000+ | 주간 다운로드: 300K+

macro를 사용해 메시지를 자동으로 추출하는 개발자 경험에 중점을 둔 최신 라이브러리입니다.

장점:

  • macro를 통한 자동 메시지 추출
  • 더 깔끔한 컴포넌트 구문
  • ICU 메시지 형식 지원
  • TypeScript 우선

단점:

  • 작은 커뮤니티
  • Babel 또는 SWC macro 필요
  • 여전히 외부 번역 관리 필요

next-intl

GitHub Stars: 8,000+ | 주간 다운로드: 1.2M+

App Router 지원, 서버 컴포넌트, 내장 타입 안전성을 갖춘 Next.js 전용으로 구축되었습니다.

장점:

  • 일급 Next.js App Router 지원
  • 서버 사이드 렌더링 친화적
  • 훌륭한 TypeScript 경험
  • 타입 안전한 번역 키

단점:

  • Next.js에 종속
  • 여전히 JSON 번역 파일 필요
  • 번역가는 여전히 개발자 참여 필요

비교 표

기능react-i18nextreact-intlLinguinext-intlbetter-i18n
JSON 파일 불필요Yes
키 추출 불필요PartialYes
번역가 친화적 UIYes
AI 기반 번역Yes
새 콘텐츠에 코드 변경 불필요Yes
CMS 기반Yes
React 호환YesYesYesYesYes
Next.js 호환YesYesYesYesYes

react-i18next: 심층 분석 {#react-i18next}

react-i18next는 React JS i18n의 지배적인 라이브러리이므로, 실제 사용 방식을 더 자세히 살펴볼 필요가 있습니다.

네임스페이스

대형 앱에서는 번역을 네임스페이스로 분리하면 파일을 관리하기 쉬워집니다.

// 네임스페이스와 함께 사용
const { t } = useTranslation('checkout');

// 번역 파일: locales/en/checkout.json
{
  "summary": "Order Summary",
  "total": "Total: {{amount}}",
  "confirm": "Confirm Order"
}

보간

번역된 문자열에 동적 값 삽입:

// 번역 키: "greeting": "Hello, {{name}}!"
t('greeting', { name: 'Alice' });
// 출력: "Hello, Alice!"

복수형

// 번역 키:
// "item_one": "{{count}} item"
// "item_other": "{{count}} items"
t('item', { count: 5 });
// 출력: "5 items"

Trans 컴포넌트

React 요소(링크, 굵은 텍스트)가 포함된 문자열의 경우:

import { Trans } from 'react-i18next';

// 번역 키: "termsText": "I agree to the <1>Terms of Service</1>"
<Trans i18nKey="termsText">
  I agree to the <a href="/terms">Terms of Service</a>
</Trans>

키 추출 문제

개발자가 새 UI 텍스트를 추가할 때마다 다음이 필요합니다.

  1. 소스 JSON 파일에 키 추가
  2. 키 추출기 실행: npx i18next-parser
  3. 업데이트된 JSON을 번역가에게 전송
  4. 번역 대기
  5. 번역을 JSON 파일로 다시 가져오기
  6. 커밋 및 배포

이 워크플로우는 모든 콘텐츠 업데이트를 느리게 만들고 개발자가 제품 관리자와 번역가 사이의 중개자가 되도록 강요하는 개발자 병목 현상을 만듭니다.


react-intl: 심층 분석 {#react-intl}

React-intl은 다른 철학적 접근 방식을 취합니다. 메시지는 별도의 JSON 파일이 아닌 컴포넌트 인라인으로 정의됩니다. defineMessages 헬퍼는 추출 가능한 메시지를 선언하는 데 사용됩니다.

import { useIntl, defineMessages } from 'react-intl';

const messages = defineMessages({
  greeting: {
    id: 'app.greeting',
    defaultMessage: 'Hello, {name}!',
    description: '홈 페이지에 표시되는 인사말',
  },
});

function Greeting({ name }) {
  const intl = useIntl();
  return <p>{intl.formatMessage(messages.greeting, { name })}</p>;
}

ICU 메시지 형식

React-intl은 복잡한 복수형 및 성별 처리를 위해 ICU 메시지 형식을 사용합니다.

// ICU를 사용한 복잡한 복수형
const message = `{count, plural,
  =0 {No items in cart}
  one {# item in cart}
  other {# items in cart}
}`;

이는 강력하지만 번역가가 올바르게 번역하려면 ICU 구문을 이해해야 하므로 종종 어려움을 겪습니다.

Provider 설정

import { IntlProvider } from 'react-intl';
import enMessages from './locales/en.json';
import frMessages from './locales/fr.json';

function App() {
  const locale = navigator.language.split('-')[0];
  const messages = locale === 'fr' ? frMessages : enMessages;

  return (
    <IntlProvider locale={locale} messages={messages}>
      <MainApp />
    </IntlProvider>
  );
}

전통적인 React 지역화의 숨겨진 비용 {#hidden-costs}

전통적인 React i18n 라이브러리는 잘 설계되어 있지만, 이것들이 도입하는 운영 오버헤드는 종종 과소평가됩니다.

1. 개발자 병목 현상

모든 콘텐츠 변경에 개발자가 필요합니다. 마케터가 CTA를 "Start free trial"에서 "Try for free"로 변경하려면 티켓을 제출하고, 개발자가 JSON 키를 업데이트하기를 기다리고, PR을 푸시하고, 배포해야 합니다. 이 병목 현상은 전체 조직을 느리게 만듭니다.

2. 대규모 JSON 파일 관리

성숙한 React 앱은 수십 개의 네임스페이스에 걸쳐 수천 개의 번역 키를 가질 수 있습니다. 5개 언어를 관리하면 파일이 5배 늘어납니다. JSON 번역 파일의 병합 충돌은 고통스럽고 오류가 발생하기 쉽습니다.

3. 키 드리프트와 고아 키

시간이 지남에 따라 키가 추가되고, 이름이 변경되고, 삭제됩니다. 엄격한 도구 없이는 고아 키(JSON에는 있지만 UI에서 더 이상 사용되지 않는 키)와 누락된 키(JSON에 추가되지 않은 UI 문자열)가 생깁니다. i18next-parser 같은 도구가 도움이 되지만 CI/CD에 통합이 필요합니다.

4. 번역가 마찰

번역가는 전문 언어학자이지, 개발자가 아닙니다. JSON 파일로 작업하도록 요청하는 것은 잘못된 도구를 사용하도록 강요하는 것입니다. 대부분의 전문 번역가는 Phrase, Lokalise 또는 Crowdin 같은 CAT(컴퓨터 지원 번역) 도구를 사용합니다. 이는 코드와 번역가 사이에 세 번째 통합 레이어가 필요하다는 의미입니다.

5. 맥락 없는 번역

번역가가 JSON 키와 문자열만 볼 때 해당 문자열이 UI 어디에 나타나는지에 대한 맥락이 없습니다. 구독 취소 페이지의 "Cancel"은 파일 업로드 다이얼로그의 "Cancel"과 다른 의미를 가집니다. 맥락 없는 번역은 품질 저하로 이어집니다.

6. 배포 결합

전통적인 설정에서 번역은 앱과 함께 번들링됩니다. 모든 번역 업데이트에 새로운 배포가 필요합니다. 이는 느리고 위험합니다. 프랑스어 번역의 오타 수정에 전체 릴리스 사이클이 필요합니다.


better-i18n으로 React 국제화를 단순화하는 방법 {#better-i18n-section}

better-i18n은 위에서 설명한 모든 문제를 해결하기 위해 구축되었습니다. React 및 Next.js 애플리케이션을 위해 특별히 설계된 AI 기반 콘텐츠 지역화 플랫폼입니다.

핵심 아이디어: 서비스로서의 콘텐츠

코드베이스에서 번역 문자열을 관리하는 대신, better-i18n은 콘텐츠를 관리형 서비스로 취급합니다. React 앱은 better-i18n CMS에 연결되고 번역이 동적으로 제공됩니다. 저장소에 JSON 파일이 없고, 키 추출도 없으며, 콘텐츠 업데이트를 위한 배포도 필요 없습니다.

작동 방식

  1. 단일 SDK 통합으로 React 앱을 better-i18n CMS에 연결합니다
  2. better-i18n UI에서 콘텐츠를 생성하고 관리합니다. JSON 없음, 콘텐츠 업데이트에 개발자 불필요
  3. 새 콘텐츠를 게시하거나 기존 콘텐츠를 변경할 때 AI가 자동으로 번역합니다
  4. React 앱이 실시간으로 번역을 수신합니다. 재빌드 없음, 재배포 없음

개발자 병목 현상 없음

better-i18n을 사용하면 마케팅 관리자가 금요일 오후 3시에 헤드라인을 업데이트하면 티켓 제출, 개발자, 배포 없이 몇 분 안에 지원되는 모든 12개 언어에 표시됩니다.

맥락 인식 AI 번역

better-i18n은 콘텐츠를 전체 맥락(페이지, 섹션, 콘텐츠 유형, 작성자 메모)과 함께 저장하기 때문에 AI 번역 엔진은 분리된 문자열만 보는 도구보다 더 높은 품질의 번역을 생성합니다. 플랫폼에서 직접 번역 메모와 검토자 워크플로우를 추가할 수도 있습니다.

CMS 기반 워크플로우

better-i18n CMS는 개발자, 마케터, 카피라이터, 번역가 등 전체 팀에게 공유 작업 공간을 제공합니다. 번역가는 JSON 파일이 아닌 목적에 맞게 구축된 번역 UI를 사용합니다. 마케터는 게시 전에 번역된 콘텐츠를 미리 볼 수 있습니다. 개발자는 코드에 머뭅니다.

기존 React 스택과 함께 작동

better-i18n은 React 프레임워크를 대체하는 것이 아니라 함께 통합됩니다. Create React App, Next.js, Remix 또는 Vite를 사용하든, better-i18n은 컴포넌트 아키텍처를 변경하지 않고 작동합니다.


코드 예시: 전통적인 방식 vs better-i18n {#code-examples}

히어로 섹션, 기능 목록, 가격 CTA가 있는 제품 랜딩 페이지를 구체적인 예시로 살펴보겠습니다.

전통적인 react-i18next 방식

코드에서 관리하는 것:

// public/locales/en/landing.json (모든 언어에 대해 하나씩)
{
  "hero": {
    "headline": "Ship your product to the world",
    "subheadline": "The fastest way to go global without slowing down your team",
    "cta_primary": "Start for free",
    "cta_secondary": "See how it works"
  },
  "features": {
    "title": "Everything you need to go global",
    "item1_title": "Instant AI Translation",
    "item1_desc": "Translate your entire product in minutes, not weeks",
    "item2_title": "No developer bottleneck",
    "item2_desc": "Marketers update content directly — no tickets, no PRs",
    "item3_title": "Real-time updates",
    "item3_desc": "Content updates go live instantly, no redeployment needed"
  }
}

컴포넌트:

// src/components/LandingHero.jsx
import { useTranslation } from 'react-i18next';

function LandingHero() {
  const { t } = useTranslation('landing');

  return (
    <section className="hero">
      <h1>{t('hero.headline')}</h1>
      <p>{t('hero.subheadline')}</p>
      <div className="cta-group">
        <a href="/signup" className="btn-primary">
          {t('hero.cta_primary')}
        </a>
        <a href="/demo" className="btn-secondary">
          {t('hero.cta_secondary')}
        </a>
      </div>
    </section>
  );
}

새 언어를 추가하려면 다음이 필요합니다.

  1. 새 JSON 파일 생성 (fr/landing.json)
  2. TMS를 통해 수동으로 번역 추가 또는 내보내기/가져오기
  3. i18next resources 구성에 fr 추가
  4. 앱 재빌드 및 재배포

better-i18n 방식

컴포넌트 (어떤 언어에도 변경 없음):

// src/components/LandingHero.jsx
// 이 컴포넌트는 i18n에 전혀 변경되지 않습니다
// 콘텐츠는 CMS에서 제공되며, better-i18n이 로케일 라우팅을 처리합니다

function LandingHero({ content }) {
  return (
    <section className="hero">
      <h1>{content.headline}</h1>
      <p>{content.subheadline}</p>
      <div className="cta-group">
        <a href="/signup" className="btn-primary">
          {content.ctaPrimary}
        </a>
        <a href="/demo" className="btn-secondary">
          {content.ctaSecondary}
        </a>
      </div>
    </section>
  );
}

새 언어를 추가하려면:

  1. better-i18n 대시보드에서 "언어 추가" 클릭
  2. AI가 모든 기존 콘텐츠를 자동 번역
  3. 완료. 새 언어가 즉시 실시간으로 제공됩니다

JSON 파일 없음. 키 추출 없음. 재빌드 없음. 재배포 없음.

동적 콘텐츠 처리

동적 콘텐츠(사용자 생성 또는 데이터베이스 기반 콘텐츠)에 대한 전통적인 접근 방식은 일반적으로 모든 문자열을 t()로 감싸고 모든 동적 문자열에 대한 키를 유지해야 합니다. 이는 종종 불가능합니다. better-i18n을 사용하면 CMS에서 관리되는 콘텐츠는 정적 UI 텍스트든 블로그 게시물이나 제품 설명 같은 장문 콘텐츠든 상관없이 구성된 모든 언어에서 자동으로 사용 가능합니다.


React i18n 모범 사례 {#best-practices}

전통적인 라이브러리를 사용하든 better-i18n을 사용하든, 이 원칙들은 모든 React 지역화 작업에 적용됩니다.

1. 처음부터 모든 문자열 외부화

JSX에 사용자 대면 문자열을 직접 하드코딩하지 마십시오. 단일 언어만으로 시작하더라도 처음부터 문자열을 외부화하면 향후 i18n이 훨씬 쉬워집니다.

2. 텍스트 확장을 위한 설계

독일어 텍스트는 일반적으로 영어에 비해 30-40% 더 깁니다. 러시아어는 50% 더 길 수 있습니다. 텍스트 확장이 레이아웃을 깨지 않도록 충분한 유연성을 갖춘 UI를 설계하십시오. 고정 너비 대신 overflow: hidden, text-overflow: ellipsis 또는 유연한 컨테이너 같은 CSS 속성을 사용하십시오.

3. 문자열 연결 피하기

연결을 통해 번역된 문자열을 만들지 마십시오.

// 잘못된 방법 — 어순이 다른 언어에서 깨집니다
const message = t('hello') + ', ' + userName + '!';

// 올바른 방법 — 보간 사용
const message = t('hello_user', { name: userName });
// 번역: "hello_user": "Hello, {{name}}!"

4. 복수형을 올바르게 처리

영어는 두 가지 복수형(단수/복수)을 가집니다. 많은 언어들은 더 많습니다. 아랍어는 여섯 가지 복수형을 가집니다. 항상 라이브러리의 복수형 처리를 사용하세요. 직접 작성하지 마십시오.

// 잘못된 방법
const label = count === 1 ? t('item_singular') : t('item_plural');

// 올바른 방법
const label = t('item', { count });
// 올바른 복수형 키와 함께: item_one, item_other, item_few 등

5. 로케일 기본 설정 저장

사용자의 언어 선택을 유지하십시오.

// 언어 변경 시
localStorage.setItem('preferred-locale', newLocale);

// 앱 초기화 시
const savedLocale = localStorage.getItem('preferred-locale');
const browserLocale = navigator.language.split('-')[0];
const locale = savedLocale || browserLocale || 'en';

6. 로케일 인식 형식 사용

날짜, 숫자, 통화에는 항상 Intl API 또는 i18n 라이브러리의 형식을 사용하십시오.

// 잘못된 방법
const formatted = '$' + price.toFixed(2);

// 올바른 방법
const formatted = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'USD',
}).format(price);
// 독일어 로케일의 경우: "1.234,56 $"
// 미국 로케일의 경우: "$1,234.56"

7. RTL을 일찍 계획

아랍어, 히브리어, 페르시아어 또는 우르두어를 지원할 계획이라면 처음부터 RTL을 계획하십시오. 물리적 속성 대신 CSS 논리적 속성을 사용하십시오.

/* 물리적 (RTL에서 깨짐) */
.container { margin-left: 16px; padding-right: 24px; }

/* 논리적 (LTR 및 RTL 모두에서 작동) */
.container { margin-inline-start: 16px; padding-inline-end: 24px; }

8. 가상 지역화로 테스트

실제 번역가에게 문자열을 보내기 전에 가상 지역화를 사용하여 UI가 텍스트 확장과 특수 문자를 처리하는지 확인하십시오.

// 가상 로케일은 "Hello, World!"를 "[Ĥéĺĺô, Ŵôŕĺď!]"로 변환합니다
// 이는 실제 번역이 도착하기 전에 레이아웃 버그를 잡습니다

9. CI에서 키 추출 자동화

키 추출이 필요한 라이브러리를 사용하는 경우 CI 파이프라인의 일부로 만드십시오. 프로덕션에서 누락된 키는 사용자에게 빈 문자열을 표시하는데, 이는 영어 텍스트를 표시하는 것보다 나쁩니다.

10. 코드 배포에서 번역 업데이트 분리

최고의 아키텍처는 콘텐츠 업데이트를 코드 릴리스로부터 분리합니다. 이것이 better-i18n 같은 CMS 기반 접근 방식이 점점 선호되는 이유입니다. 번역은 애플리케이션 배포와 독립적으로 업데이트하고 게시할 수 있습니다.


자주 묻는 질문 {#faq}

React i18n과 React 지역화의 차이점은 무엇인가요?

**React i18n (국제화)**는 여러 언어를 지원할 수 있는 앱을 만드는 엔지니어링 작업을 말합니다. 인프라 설정, 라이브러리 선택, 로케일 인식이 가능하도록 코드 구조화. **React 지역화 (l10n)**는 특정 로케일에 맞게 앱을 실제로 적응시키는 것을 말합니다. 특정 언어와 지역에 대한 번역된 텍스트, 날짜 형식, 문화적 관습. i18n은 전제 조건이고, l10n은 지속적인 작업입니다.

어떤 React i18n 라이브러리를 사용해야 하나요?

대부분의 새 프로젝트에서 react-i18next는 생태계 규모와 유연성 때문에 가장 안전한 선택입니다. Next.js 프로젝트의 경우 next-intl이 탁월한 App Router 통합과 타입 안전성을 제공합니다. JSON 파일 관리를 완전히 없애고 콘텐츠 팀에 자율성을 부여하고 싶다면 better-i18n이 전통적인 라이브러리 레이어 전체를 제거하고 CMS 기반 워크플로우를 제공합니다.

기존 React 앱에 i18n을 어떻게 추가하나요?

기존 React 앱에 i18n을 추가하는 것은 세 단계로 이루어집니다. (1) 컴포넌트의 모든 하드코딩된 문자열 감사, (2) i18n 라이브러리 선택 및 구성, (3) 문자열을 번역 파일로 추출하고 하드코딩된 텍스트를 번역 함수 호출로 교체. better-i18n을 사용하면 프로세스가 더 간단합니다. SDK를 연결하고 컴포넌트 로직을 변경하지 않고 콘텐츠를 CMS로 마이그레이션합니다.

React i18n이 성능에 영향을 미치나요?

전통적인 라이브러리를 사용하면 번역 JSON 파일이 일반적으로 앱과 함께 번들링되거나 로케일별로 지연 로딩됩니다. 대형 번역 번들은 초기 로드 시간에 영향을 줄 수 있습니다. 네임스페이스 분리와 지연 로딩(react-i18next 지원)이 이를 완화합니다. better-i18n은 엣지 CDN을 통해 콘텐츠를 제공하여 사용자 위치에 관계없이 최소한의 지연 시간으로 번역이 제공됩니다.

React i18n에서 동적 콘텐츠(사용자 생성 콘텐츠)를 어떻게 처리하나요?

사용자 이름, 게시물 제목, 제품 설명과 같은 동적 콘텐츠는 정적으로 번역할 수 없습니다. 옵션에는 다음이 포함됩니다. (1) API를 통한 런타임 기계 번역, (2) 데이터베이스에 사전 번역된 버전 저장, (3) 정적 UI 문자열과 장문 동적 콘텐츠를 단일 워크플로우로 관리하는 better-i18n 같은 콘텐츠 플랫폼 사용.

react-i18next를 Next.js와 함께 사용할 수 있나요?

네. React-i18next는 Next.js Pages Router와 App Router 모두에서 작동하지만, App Router 통합에는 서버 컴포넌트의 신중한 처리가 필요합니다. Next.js 프로젝트의 경우 next-intl이 종종 더 적합합니다. 기본 서버 컴포넌트 지원을 갖춘 Next.js 전용으로 구축되었기 때문입니다.

React 앱이 지원해야 할 언어는 몇 개인가요?

타겟 시장이 사용하는 언어부터 시작하십시오. 미국 중심의 SaaS 제품의 경우 스페인어, 프랑스어, 포르투갈어, 독일어를 추가하면 일반적으로 도달할 가능성이 있는 비영어권 시장의 80% 이상을 커버합니다. 언어 우선순위를 정하기 전에 분석을 통해 기존 사용자가 어디서 오는지 파악하십시오.

React 앱을 국제화하지 않는 비용은 무엇인가요?

비용은 시장 제외입니다. 전 세계 인터넷 사용자의 75%가 비영어권 사용자입니다. 지역화 없는 앱은 비영어 쿼리에 대해 Google에서 순위를 매길 수 없고, 비영어권 방문자를 효과적으로 전환할 수 없으며, 국제 사용자에게 제품이 그들을 위해 구축되지 않았다는 신호를 보냅니다. 대부분의 소프트웨어 제품의 경우 첫 해에 3-5개 언어를 추가하면 ROI가 플러스가 됩니다.

better-i18n은 번역 품질을 어떻게 처리하나요?

better-i18n은 맥락 인식 AI 번역을 사용합니다. AI는 번역할 문자열뿐만 아니라 콘텐츠 유형, 페이지 위치, 추가한 번역 메모도 볼 수 있습니다. 플랫폼은 또한 인간 검토 워크플로우를 지원합니다. 전문 번역가가 AI 생성 번역을 검토하고 승인한 후 실시간으로 제공됩니다. 이를 통해 AI의 속도와 인간 품질 보증이 결합됩니다.

better-i18n은 대형 React 애플리케이션에 적합한가요?

네. better-i18n은 단일 제품을 가진 스타트업부터 여러 제품과 수십 개 언어를 관리하는 엔터프라이즈까지 확장 가능하도록 구축되었습니다. CMS는 역할 기반 액세스 제어, 승인 워크플로우, 시간이 지남에 따라 AI 품질을 향상시키는 번역 메모리를 갖춘 팀 협업을 위해 설계되었습니다.


결론

React i18n은 상당히 발전했습니다. 전통적인 접근 방식인 react-i18next 설치, 모든 언어에 대한 JSON 파일 생성, 번역 키 수동 유지 관리는 여전히 작동하지만, 제품이 확장됨에 따라 팀을 느리게 만드는 지속적인 운영 부담을 만듭니다.

better-i18n 같은 현대적인 대안은 근본적으로 다른 철학을 나타냅니다. 코드에서 분리되어 콘텐츠에 가장 가까운 사람들(마케터, 작가, 번역가)이 관리하고 AI로 구동되는 서비스로서의 콘텐츠. 새 언어 추가가 개발 프로젝트가 아닌 제품 결정이 됩니다.

새 React 앱을 시작하든 기존 앱에 i18n을 추가하든, 목표는 동일합니다. 사용자의 언어로, 그들의 문화적 맥락에서, 지역화를 개발자의 영구적인 수고의 원천으로 만들지 않고 제품을 접근 가능하게 만드는 것입니다.

복잡함 없이 React i18n을 앱에 추가할 준비가 되셨나요? better-i18n 시작하기 — 몇 분 안에 React 앱을 연결하고 나머지는 콘텐츠 팀이 처리하도록 하십시오.


마지막 업데이트: 2024년 3월. 키워드: react 국제화, react i18n, react 지역화, react js i18n, react js 지역화, reactjs 지역화.

Comments

Loading comments...