i18next에는 formatting이 가능하다. Formatting – i18next documentation
포맷팅에 관한 자세한 내용은 공식문서를 살펴보면 좋을 것이다.
Javascript 기본 Intl.NumberFormat()
함수로는 1,000 원
을 표현할 수 없다.
굳이 왜 Intl.NumberFormat()
을 말하냐면 i18next의 currency 포맷팅이 Intl.NumberFormat
으로 한다.
화폐단위를 포맷팅하게 되면
// {{상품_가격}}: {{상품_가격, price}}
t('{{prcie}}', {
상품_가격: 1000,
formatParams: {
상품_가격: {
currency: 'USD',
currencyDisplay: 'name'
}
}
})
// 결과값 1,000 미국 달러
Code language: TypeScript (typescript)
이렇게 나오게된다. 하지만 우리는 미국 달러
없이 달러
라고 나오기를 원하고있다.
- 미국 달러
- 캐나다 달러
이런식으로 여러 나라를 동시에 표현할때면 맞겠지만 우리 서비스에는 미국 달러
만 사용해서 달러
라 표기해도 문제가 없다할때 달러
라고 표기해야한다.
코드로만 표기한다면 그냥 reaplceAll
해서 제거하면 되지만 우리는 번역 툴들을 사용할것이고 gettext
i18next
와 같은 표준을 사용해서 i18n
을 호환되도록 만들것이다.
i18next에 custom fomatter를 추가해서 나라 명칭이 나온다면 제거하자
i18n.services.formatter?.add('currency', (value, lng, options) => {
const overrideOptions = { ...options }
// 기본값을 currency로 설정한다.
if (!overrideOptions?.style) {
overrideOptions.style = 'currency'
}
// 대한민국 통화 커스텀 포맷터
// Javascript의 기본 Intl.NumberFormat에서 name의 값은 `대한민국 원`으로만 지원한다.
// 하지만우리는 `1,000 원`을 원한다.
// 모든 나라 화폐에 대해서 동일하게 화페 단위만 가져올 것이다.
// - 대한민국 원
// - 미국 달러
// - 유로
// - 일본 엔화
if (
overrideOptions?.removeCountry &&
overrideOptions?.currencyDisplay === 'name'
) {
const getCurrencyName = new Intl.NumberFormat(
lng,
overrideOptions
).format(value)
const result = getCurrencyName.split(' ')
// 가격제거
const price = result.shift()
// 기본 template
const template = overrideOptions?.template || '[[amount]] [[currency]]'
return template
.replace('[[amount]]', String(price))
.replace('[[currency]]', currency.slice(-1)[0])
}
})
Code language: TypeScript (typescript)
이제 i18next에서 기본적으로 넣어둔 currency에 대한 포맷팅을 덮어씌우게된다.
i18next에서 사용하기
const price = 234567
t('{{상품_가격}}', {
상품_가격: price,
formatParams: {
상품_가격: {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'name',
removeCountry: true, // custom 옵션
}
}
})
Code language: TypeScript (typescript)