반응형
TL:DR
컴포넌트 / 디자인 기반으로 translation key를 설계하자
개요 :
최근에 국제화가 필요한 프로젝트를 진행하면서,
translation key 설계를 잘못해서 곤란한 경우가 있었습니다.
애초에 translation key를 파라미터를 이용해 동적으로 사용할 수 있도록 디자인 했으면 좋았을 것이란 생각이 들었는데요,
처음에는 의미론적으로 키 디자인을 접근헀는데,
좀 더 키에 컴포넌트의 컨텍스트를 담았으면 좋지 않았을까 생각해서,
다른 사람들의 접근법을 리서치해보다 괜찮은 아이디어가 있는 것 같아 공유해봅니다.
원문 : 힘들게 배운 프로젝트 국제화 적용 경험의 교훈들
translation key를 언어 독립적으로 활용하세요
언어(종종 영어)를 기본 언어로 사용할 수 있는 옵션을 제공하는 많은 라이브러리가 있습니다.
영어로 번역할 필요가 없으므로 시간을 절약할 수 있습니다.
그러나 이제 의미론에 의존적인 키가 있습니다.
따라서 누군가가 애플리케이션을 잘 모른다면 문맥에 따라 완전히 잘못 번역할 수 있습니다.
Next 또는 Continue와 같은 간단한 문자열은 애플리케이션의 여러 위치에서 나타날 수 있지만 위치에 따라 의미가 매우 다를 수 있습니다. 문맥 없이 프랑스어, 스페인어 또는 기타 언어로의 직역 번역은 매우 부적절할 수 있습니다.
번역 키는 언어에 구애받지 않으며 번역가가 텍스트의 목적을 나타내는 데 도움이 되도록 많은 컨텍스트를 추가할 수 있습니다. Continue와 같은 문자열 대신 form:step_1:primary_button으로 해당 문자열이 나타날 위치를 표현할 수 있습니다.
이는 페이지 컨텍스트에서 영어 버전을 볼 수 있는 참조 문서에 나타날 수 있습니다.
물론 문맥에 독립으로 아무데서나 쓰이는 컴포넌트의 텍스트는
generic:help 또는 generic:continue와 같은 일반적인 번역을 가질 수도 있습니다.
마크업을 포함하는 네이밍 컨벤션을 사용하세요
때로는 굵게, 기울임꼴, 밑줄, 링크와 같은 (html) 마크업을 포함하는 번역이 필요한 문자열이 있습니다.
번역가와 개발자가 스트링 대신 마크업이 필요한 시점을 알 수 있도록 규칙을 만들어야 합니다.
접두사 또는 접미사로 충분합니다.
예를 들어 -html 접미사는 about:content-html과 같습니다.
(내용물은 스트링 대신 마크업)
와일드카드 주입을 지원하세요
프로그래밍 방식의 값을 포함하는 번역이 필요한 날은 멀지 않습니다.
(ex 장바구니에 총 물건 갯수 10이 10개의 아이템 리스트를 통해 동적으로 삽입되는 것처럼.)
자체 언어의 기능을 사용하기 보단, 라이브러리에서 지원하는 적절한 와일드카드 자리 표시자를 사용합니다.
또한 와일드카드의 순서는 언어에 따라 변경될 수 있으므로 와일드카드의 순서를 이용하는 것보단 명명하는 것을 선호합니다.
your cart contains !{itemCount} items.
단, 복수형을 고려하세요
위의 예에서 복수화가 문제가 되는 것을 이미 보았습니다.
your cart contains 1 items
간단한 이름 지정 규칙이 여기에 도움이 될 수 있습니다.
물론 이에 대한 기본 제공 지원이 있는 라이브러리가 있습니다만, 아래와 같이 간단히 생성합니다.
shopping:cart_count:singular: “your cart contains !{itemCount} item.”
shopping:cart_count:plural: “your cart contains !{itemCount} items.”
번역 파일의 예시
번역 파일을 이해할 수 있는 청크로 구성하는 것은 애플리케이션에 따라 다르지만
항상 디자인/컴포넌트기반 접근 방식을 사용하여 분할할 수 있습니다.
다음은 예입니다.
button:forward: “Next”
button:backward: “Previous”
page:about:title: “About this app”
page:about:content-html: “<p>About blabla.</p>”
page:stats:viewcount-dynamic-singular: “Your site has !{viewCount} view”.
page:stats:viewcount-dynamic-plural: “Your site has !{viewCount} views”.
page:stats:viewcount-dynamic-none: “Your site has no views yet.”
page:stats:wallet-dynamic: “Current credit: !{credit}”
page:stats:primary-button: “Enable on my site”
button:backward: “Previous”
page:about:title: “About this app”
page:about:content-html: “<p>About blabla.</p>”
page:stats:viewcount-dynamic-singular: “Your site has !{viewCount} view”.
page:stats:viewcount-dynamic-plural: “Your site has !{viewCount} views”.
page:stats:viewcount-dynamic-none: “Your site has no views yet.”
page:stats:wallet-dynamic: “Current credit: !{credit}”
page:stats:primary-button: “Enable on my site”
키가 약간 길 수 있습니다.
기호 또는 단일 문자를 사용하여 사용법을 표시하도록 선택할 수 있습니다
(d는 동적, s/p/n은 복수화, m은 마크업).
이 파일에 뛰어드는 모든 사람을 위해 저는 아무 것도 문서화할 필요가 없습니다.
요약:
- 컨텍스트를 잃지 않으려면 언어에 구애받지 않는 키를 사용하십시오.
- 마크업, 동적 값 및/또는 단, 복수의 지원을 나타내기 위해 키에 명명 규칙을 사용합니다.
- 명명된 주입을 사용하여 순서 문제를 방지합니다.
마치며
라틴 문자의 한계를 넘어서 진정으로 글로벌하게 된다면 문자 세트, 인코딩, 읽기 방향 등과 관련된 더 깊은 문제에 직면하게 될 것입니다!
팁 : 국제화 타이핑하기
// src/i18n-resources.d.ts
import 'react-i18next'
declare module 'react-i18next' {
export interface Resources {
translation: typeof import('../public/locales/en/translation.json')
}
}
https://stackoverflow.com/questions/58277973/how-to-type-check-i18n-dictionaries-with-typescript
추가로 볼만한 글 :
원https://medium.com/@danduan/translating-react-apps-using-i18next-d2f78bc87314
반응형
'FrontEnd' 카테고리의 다른 글
타입스크립트 : 파라미터 타입(Parameters)과 리턴 타입(ReturnType) (0) | 2022.07.22 |
---|---|
디자인 시스템 만들기 시리즈 1편 : 디자인 토큰 소개 (0) | 2022.07.21 |
리액트를 직접 만들며 알아보는 렌더/커밋/조정 알고리즘 (1) | 2022.07.19 |
리액트 디자인 패턴 : 선언적 컴포넌트 설계 (declarative component design) (0) | 2022.07.19 |
Valtio의 프록시 상태관리가 어떻게 동작할까? (React Part) (1) | 2022.07.18 |