FE

[vue-i18n] 2. 번역 리소스

규로로 2024. 12. 7. 22:48

이전 글: 2024.12.07 - [FE] - [vue-i18n] 1. 시작하기

다음 글: -


vue.js v3.4.25, vue-i18n v9.13.1 기준 작성

1. 리소스 파일 분리

1절에서 작성한 것과 같이 번역 리소스는 messages에 들어간다. 가장 상위의 key는 locale 값, 그 아래로는 작성된 번역 리소스가 들어간다.

 

가장 간단하게 사용하려면 messages에 리소스를 직접 작성한다. 아래는 1절의 예제에서 사용했던 코드다.

messages: {
	en: {
		message: 'hello world',
	},
	ko: {
		message: '안녕, 세계',
	},
	ja: {
		message: 'こんにちは、世界',
	},
}

 

하지만, 번역해야 될 텍스트가 많아질수록 위의 방법은 관리하기가 힘들어지니 각 언어별로 파일을 따로 만들어 import 하도록 한다.

아래와 같이 각 언어별로 별도의 파일을 만들고

// src/locales/en.json
{
  message: 'hello world'
}
// src/locales/ko.json
{
  message: '안녕, 세계'
}
// src/locales/ja.json
{
  message: 'こんにちは、世界'
}

 

앞의 예제를 다시 작성해 보면 다음과 같다.

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createI18n } from 'vue-i18n'
import ko from './locales/ko.json'
import en from './locales/en.json'
import ja from './locales/ja.json'

const app = createApp(App)

const i18n = createI18n({
  locale: 'ko',                 
  fallbackLocale: 'en',         
  legacy: false,               
  messages: { en, ko, ja }  // 깔끔하다
})
app.use(i18n)

app.mount('#app')

 

2. key와 value

작성된 리소스에서 번역 결과를 가져오기 위해서는 해당하는 key를 string 형태로 전달해주기만 하면 된다.

<div>{{ t('message') }}</div>

 

이와 같이 작성할 경우 현재 언어 파일에서 message를 key로 가진 value가 출력되게 된다.

 

만약, 다음과 같이 작성된 ko.json 파일이 있다고 하자.

// src/locales/ko.json
{
  common: {
    gender: {
      male: '남자',
      female: '여자',
    },
  },
}

 

이 경우에도 마찬가지로 번역하고자 하는 항목의 key를 다음과 같이 전달해 주면 된다.

<div>{{ t('common.gender.male') }}</div>

 

간단하다.

 

동적으로 할당되는 값을 key로 사용할 때도 동일하다. string 형태로만 넣어주면 된다.

<div>{{ t(`common.gender.${gender}`) }}</div>

 

3. 외부 변수 사용하기

텍스트 안에 변수를 받아 사용해야하는 경우, 언어마다 지정된 위치에 변수 표시만 해주면 된다.

예를 들어, 다음과 같이 json 파일을 작성하고

// src/locales/ko.json
{
  color: '선택한 색상 값은 {color}입니다.'
}
// src/locales/en.json
{
  color: 'The selected color value is {color}.'
}

 

사용할 때는 아래와 같이 해당 변수명에 맞게 할당해 주면 된다.

<div>{{ t('color', { color: '#FFFFFF' }) }}</div>

 

일반 텍스트가 아니라 숫자만을 할당하는 경우에는

// src/locales/ko.json
{
  total: '총 합게는 {n}입니다.'
}
<div>{{ t('total', 12 ) }}</div>

 

"{n}"을 사용하면 숫자 변수는 자동으로 전달된다.

 

변수는 여러개 사용 가능하다. 마찬가지로 변수가 들어갈 자리에 자리 표시만 해주고 지정된 이름에 맞게 값을 할당해 준다.

// src/locales/ko.json
{
  error: '\"{name}\" 업로드에 실패했습니다. {reason} 파일을 다시 선택해주세요.'
}
// src/locales/en.json
{
  error: 'Failed to upload \"{name}\". {reason} Please select the file again.'
}

 

사용 방법도 동일하다.

<div>{{ t('error', { name: 'favicon.png', reason: 'The file is too large.' }) }}</div>

 

변수로 텍스트도 숫자도 아닌 배열을 할당하고 싶을 때는, 자리 표시자에 index 번호를 표시해 주면 된다.

// src/locales/ko.json
{
  date: '선택한 요일은 {0}, {1], {2}입니다.'
}
// src/locales/en.json
{
  date: 'The selected days of the week are {0}, {1}, and {2}.'
}
<div>{{ t('date', ['월요일', '화요일', '토요일']) }}</div>

 

위와 같이 작성하면 각 index 번호에 맞게 텍스트가 들어가게 된다.

 

4. 내부 변수 사용하기

번역 텍스트를 파일 내부에서 재활용해야 하는 경우에도 변수 화하여 사용할 수 있다. 예를 들어 다음과 같이 ‘확인’이라는 텍스트를 사용한다고 할 때,

// src/locales/ko.json
{
  button_confirm: '확인',
  alert_modal_button: '@:button_confirm'
}
// src/locales/en.json
{
  button_confirm: 'Confirm',
  alert_modal_button: '@:button_confirm'
}

 

이와 같이 "button_confirm"이라는 키로 설정해 두고 "@:button_confirm"처럼 키 이름 앞에 "@:"을 붙여 재사용할 수 있다.

 

5. 복수형 표현

한국어, 중국어 또는 일본어에서는 나타나지 않지만, 대부분의 유럽 언어들에서는 단수와 복수를 구분하여 표현한다. 이를 위해서 구분자 "|"를 사용하여 단수형과 복수형을 모두 작성해줘야 한다.

 

만약, 다음과 같이 번역 파일을 작성하고 사용했을 때는

// src/locales/ko.json
{
  car: '자동차 {n}대'
}
// src/locales/en.json
{
  car: 'a car | {n} cars'
}
<div>{{ t('car', 1) }}</div>
<div>{{ t('car', 5) }}</div>

 

각각, 다음과 같은 결과가 나오게 된다.

// 한국어
자동차 1대
자동차 5대

// 영어
a car
5 cars

 

위의 예시에서 n의 자리 0을 넣는다면 "자동차 0대" 또는 "0 cars"라는 결과를 얻을 것이다. 하지만, 개수가 0일 때를 구분하여 표현하고 싶다면 다음과 같이 작성하면 된다.

// src/locales/ko.json
{
  car: '자동차 {n}대'
}
// src/locales/en.json
{
  car: 'no cars | a car | {n} cars'
}
<div>{{ t('car', 0) }}</div>
<div>{{ t('car', 1) }}</div>
<div>{{ t('car', 5) }}</div>

 

이때의 번역 결과는 아래와 같다.

// 한국어
자동차 0대
자동차 1대
자동차 5대

// 영어
no cars
a car
5 cars

 

같은 예시에서 한국어에도 "없음" 표시를 구분해서 하고 싶다면 "자동차 없음 | 자동차 {n} 대 | 자동차 {n} 대"와와 같이 작성한다. 표현하려는 가짓수를 맞추는 것만 주의하면 된다.


참고: 

[1] Vue I18n

'FE' 카테고리의 다른 글

Vue 프로젝트에 Playwright 적용하기  (1) 2024.12.08
Vue 프로젝트에 Airbnb ESLint 적용하기  (0) 2024.12.08
[vue-i18n] 1. 시작하기  (0) 2024.12.07
국제화(i18n)와 지역화(L10n)  (1) 2024.12.07
TailwindCSS 설치  (0) 2024.12.07