EmDash의 관리자 UI는 메시지 추출에 Lingui를, 번역 진행 상황 추적에 Lunaria를 사용하여 번역을 지원합니다. 모든 번역은 PO(gettext) 파일에 저장되며, 로케일당 하나의 파일입니다.
번역 현황
모든 로케일의 현재 진행 상황은 번역 대시보드에서 확인할 수 있습니다.
번역할 수 있는 사람
번역은 원어민 또는 유창한 화자가 제출해야 합니다. 기계 생성 번역은 허용하지 않습니다. AI 도구를 사용하여 지원하는 경우, 모든 문자열을 직접 검토하고 실제 화면에서 결과를 테스트해야 합니다(아래의 번역 테스트 참조).
번역이 없는 것이 잘못된 번역보다 낫습니다. 잘못된 번역은 영어 폴백을 표시하는 것보다 더 나쁩니다 — 사용자를 적극적으로 오도하기 때문입니다.
파일 구조
번역 카탈로그는 packages/admin/src/locales/에 있습니다:
packages/admin/src/locales/
├── en/
│ └── messages.po # English (source)
├── de/
│ └── messages.po # German
└── ...
각 .po 파일에는 msgid/msgstr 쌍이 포함되어 있습니다. msgid는 영어 원문이고, msgstr은 여러분의 번역입니다. 빈 msgstr은 “아직 번역되지 않음”을 의미하며, Lingui는 런타임에 영어로 폴백합니다.
문자열 번역하기
-
번역 대시보드를 확인하여 작업이 필요한 부분을 파악합니다. 중복 작업을 피하기 위해 열린 PR도 확인하세요.
-
저장소를 Fork하고 브랜치를 생성합니다:
git checkout -b i18n/de -
여러분의 로케일 PO 파일을 엽니다(예:
packages/admin/src/locales/de/messages.po). -
번역을 입력합니다. 각 항목은 다음과 같은 형태입니다:
#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr ""msgstr을 입력합니다:#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr "Mit Passkey anmelden" -
번역을 테스트합니다(아래 참조).
-
PR을 생성하여
main을 대상으로 합니다. 제목 형식:i18n(de): add/update German translations.
번역해야 하는 것
- 각 항목의
msgstr값.
번역하지 말아야 하는 것
msgid값 — 이것은 조회 키입니다.{error},{email},{label}같은 보간 플레이스홀더 — 그대로 유지하세요.<0>,</0>같은 XML 스타일 태그 — 이것은 대화형 요소(링크, 버튼)를 감쌉니다. 태그는 유지하고 태그 사이의 텍스트를 번역하세요.#:로 시작하는 주석 — 이것은 Lingui가 추가한 소스 참조입니다.
보간과 태그
일부 문자열에는 플레이스홀더와 태그가 포함되어 있습니다:
msgid "Authentication error: {error}"
msgstr "Authentifizierungsfehler: {error}"
msgid "Don't have an account? <0>Sign up</0>"
msgstr "Noch kein Konto? <0>Registrieren</0>"
msgid "If an account exists for <0>{email}</0>, we've sent a sign-in link."
msgstr "Falls ein Konto für <0>{email}</0> existiert, haben wir einen Anmeldelink gesendet."
플레이스홀더({error}, {email})는 런타임에 동적 값으로 대체됩니다. 태그(<0>...</0>)는 React 컴포넌트를 감쌉니다. 두 가지 모두 번역에서 원문과 정확히 동일하게 나타나야 합니다 — 같은 이름, 같은 중첩 구조.
번역 테스트
-
컴파일하고 데모를 실행합니다:
pnpm run locale:compile pnpm build pnpm --filter emdash-demo dev -
로케일을 전환하고 관리자 설정 페이지에서 번역이 올바르게 표시되는지 확인합니다.
의사 로케일
EmDash에는 래핑된 모든 문자열을 악센트가 붙은 유사 문자로 변환하는 의사 로케일이 내장되어 있습니다 — "Dashboard"는 "Ðàšĥƀöàřð"가 됩니다. 의사 로케일이 활성화된 상태에서 일반 영어로 표시되는 문자열은 t..“ 래퍼가 누락되었거나 카탈로그 외부에서 온 것입니다.
활성화하려면 데모 디렉터리의 .env 파일에 다음을 추가합니다:
EMDASH_PSEUDO_LOCALE=1
개발 서버를 재시작하세요. 의사 로케일은 로그인 페이지와 설정의 언어 선택기에 Pseudo로 표시됩니다. 전환하면 래핑되지 않은 문자열을 한눈에 발견할 수 있습니다.
새로운 언어 추가
여러분의 언어에 아직 PO 파일이 없는 경우:
-
packages/admin/src/locales/locales.ts에 로케일을 추가합니다:export const LOCALES: LocaleDefinition[] = [ { code: "en", label: "English", enabled: true }, { code: "de", label: "Deutsch", enabled: true }, // ... { code: "ja", label: "日本語", enabled: false }, // add yours ];이것이 유일한 데이터 소스입니다 —
lingui.config.ts,lunaria.config.ts및 관리자 런타임 모두 이 파일에서 로케일 목록을 가져옵니다. 번역 커버리지가 100%가 아니라면enabled를false로 설정하세요 — 충분한 커버리지에 도달하면 활성화할 것입니다. -
추출을 실행하여 빈 PO 파일을 생성합니다:
pnpm run locale:extract이렇게 하면 번역할 모든 문자열이 포함된
packages/admin/src/locales/{your-locale}/messages.po가 생성됩니다. -
위의 단계에 따라 번역하고 테스트합니다.
번역 기준
정확성
번역은 원어민 수준으로 영어 원문을 충실하게 반영해야 합니다. 의미를 추가, 삭제 또는 재해석하지 마세요. 원문의 의미가 모호한 경우 #: 주석에서 소스 파일 위치를 확인하고 컴포넌트 코드를 읽어 컨텍스트를 이해하세요.
일관성
로케일 내에서 일관된 용어를 사용하세요. 한 곳에서 “collection”을 “Sammlung”으로 번역했다면 다른 곳에서 “Kollektion”으로 바꾸지 마세요. 이미 번역이 있는 언어라면 시작하기 전에 기존 PO 파일을 통독하여 확립된 용어에 맞추세요.
어조
관리자 UI는 직접적이고 전문적인 어조를 사용합니다. 여러분의 언어에서도 이를 맞추세요 — 지나치게 격식적이거나 지나치게 캐주얼한 표현은 피하세요.
AI 지원 번역
AI 도구를 사용하여 번역 초안을 작성할 수 있지만:
- 모든 문자열을 직접 검토해야 합니다. AI 도구는 유창한 화자만 알아챌 수 있는 미묘한 오류를 만듭니다 — 잘못된 어체, 부자연스러운 표현, 부정확한 기술 용어 등.
- 실행 중인 관리자 UI에서 결과를 테스트해야 합니다. AI 도구는 레이아웃 제약이나 UI 컨텍스트를 인식하지 못합니다.
- PR 설명에 AI 사용을 공개하세요.
- 명백히 검토되지 않은 기계 번역 PR은 닫힙니다.
부분 번역
부분 번역도 환영합니다. 하나의 PR에서 모든 문자열을 번역할 필요는 없습니다 — 어떤 진전이든 도움이 됩니다. 번역되지 않은 문자열은 런타임에 영어로 폴백됩니다.