Skip to main content

Vue i18n: vue-i18n 국제화 설정 완벽 가이드

설치부터 프로덕션까지, Composition API로 vue-i18n을 설정하고 CLDR 규칙으로 복수형을 처리하며 컴포넌트 보간과 스마트 로케일 폴백 체인을 사용해 보세요.

1

vue-i18n 설치

vue-i18n은 Vue.js 공식 국제화 플러그인이에요. 반응형 번역, ICU 방식 복수형, 컴포넌트 보간, 날짜/시간 및 숫자 서식을 제공하고 Options API와 Composition API를 모두 지원해요.

Terminal
npm install vue-i18n@9
2

vue-i18n 설정

createI18n()으로 i18n 인스턴스를 만들고 Vue 플러그인으로 등록하세요. 로케일 메시지를 정의하고 기본 로케일과 폴백 로케일을 설정하세요. vue-i18n은 레거시(Options API) 모드와 컴포지션(Composition API) 모드를 모두 지원해요.

src/i18n.ts
// src/i18n.ts
import { createI18n } from 'vue-i18n'
import en from './locales/en.json'
import de from './locales/de.json'

const i18n = createI18n({
  legacy: false,           // Use Composition API mode
  locale: 'en',            // Default locale
  fallbackLocale: 'en',   // Fallback locale
  messages: { en, de },
})

export default i18n
src/main.ts
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'

const app = createApp(App)
app.use(i18n)
app.mount('#app')
'Not available in legacy mode' 오류가 표시되면 Composition API i18n 호출(useI18n())과 레거시 모드 설정을 혼용하고 있기 때문이에요. Composition API 모드를 사용하려면 createI18n()에서 legacy: false를 설정하거나 Options API의 $t() 구문만 일관되게 사용하세요.
3

템플릿에서 번역 사용

vue-i18n은 템플릿에서 $t() 함수(Options API)를 제공하고 useI18n()에서 t() 함수(Composition API)를 제공해요. 두 함수 모두 번역 키와 보간에 사용할 선택 사항인 명명된 매개변수나 목록 매개변수를 받아요.

src/locales/en.json
// src/locales/en.json
{
  "nav": {
    "home": "Home",
    "about": "About",
    "settings": "Settings"
  },
  "greeting": "Hello, {name}!",
  "cart": {
    "itemCount": "no items | one item | {count} items"
  }
}

// src/locales/de.json
{
  "nav": {
    "home": "Startseite",
    "about": "Über uns",
    "settings": "Einstellungen"
  },
  "greeting": "Hallo, {name}!",
  "cart": {
    "itemCount": "keine Artikel | ein Artikel | {count} Artikel"
  }
}
4

복수형 처리

vue-i18n은 파이프로 구분한 형식과 $tc() 함수(레거시) 또는 개수 매개변수를 받는 t()(Composition API)로 복수형을 지원해요. 로케일 메시지에 파이프 구분자로 복수형을 정의하세요: 'no items | one item | {count} items'.

MyComponent.vue
<template>
  <div>
    <!-- Simple translation -->
    <h1>{{ $t('nav.home') }}</h1>

    <!-- With variables -->
    <p>{{ $t('greeting', { name: userName }) }}</p>

    <!-- In attributes -->
    <input :placeholder="$t('nav.settings')" />

    <!-- Composition API -->
    <p>{{ greeting }}</p>
  </div>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'

const { t } = useI18n()
const userName = 'Alice'
const greeting = t('greeting', { name: userName })
</script>
파이프로 구분한 복수형 구문은 최대 세 가지 형식(zero | one | other)의 기수 복수형만 지원해요. CLDR 복수형 규칙이 복잡한 언어(아랍어, 러시아어, 폴란드어)에는 ICU MessageFormat 구문이나 명시적인 CLDR 범주 매핑이 있는 @.plural 수정자를 사용하세요.
5

로케일 폴백 체인 추가

vue-i18n의 내장 fallbackLocale은 로케일별 체인이 아닌 평면 폴백 로케일 목록만 지원해요. pt-BR 사용자는 키가 누락되면 pt-PT 대신 영어로 대체돼요. vue-i18n-locale-chain은 설정 가능한 딥 머지 체인을 추가해 지역 사용자가 가장 가까운 번역을 볼 수 있게 해요.

Plurals.vue
<template>
  <div>
    <!-- Pipe-separated plurals -->
    <p>{{ $t('cart.itemCount', count) }}</p>

    <!-- Named plurals (recommended for complex languages) -->
    <p>{{ $t('orders', { n: orderCount }) }}</p>
  </div>
</template>

<!-- In your locale file: -->
<!-- "orders": "{n} order | {n} orders" -->
vue-i18n-locale-chain은 로드 시점에 메시지를 딥 머지해요. 병합된 메시지 세트는 vue-i18n의 반응성 시스템이 캐시하므로 폴백 조회로 인한 런타임 성능 저하가 없어요.
6

번역 자동화

vue-i18n 설정이 끝나면 AI로 로케일 JSON 파일을 번역하세요. IDE에서 AI 어시스턴트에게 원본 파일 번역을 요청하거나 CI/CD 파이프라인에 번역을 통합해 현지화를 완전히 자동화할 수 있어요.

LanguageSwitcher.vue
<template>
  <select v-model="locale">
    <option v-for="lang in availableLocales" :key="lang" :value="lang">
      {{ lang }}
    </option>
  </select>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'

const { locale, availableLocales } = useI18n()
</script>
src/i18n.ts (lazy loading)
// src/i18n.ts
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  legacy: false,
  locale: 'en',
  fallbackLocale: 'en',
  messages: {},
})

export async function loadLocale(locale: string) {
  const messages = await import(`./locales/${locale}.json`)
  i18n.global.setLocaleMessage(locale, messages.default)
  i18n.global.locale.value = locale
}

export default i18n
7

로케일 폴백 체인 설정

지역 사용자가 바로 영어로 넘어가지 않고 가장 가까운 번역을 볼 수 있도록 로케일별 폴백 체인을 설정하세요. vue-i18n은 객체 형식 fallbackLocale로 로케일별 체인을 정의할 수 있어요.

src/i18n.ts
// src/i18n.ts
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  legacy: false,
  locale: 'pt-BR',
  fallbackLocale: {
    'pt-BR': ['pt', 'en'],
    'zh-Hant-TW': ['zh-Hant', 'zh', 'en'],
    'es-419': ['es', 'en'],
    default: ['en'],
  },
  messages: {
    en: { /* ... */ },
    pt: { /* ... */ },
    'pt-BR': { /* ... */ },
  },
})
fallbackLocale 객체에서는 로케일마다 다른 체인을 정의할 수 있어요. pt-BR에는 pt, en 순서의 폴백 체인을 적용하고 zh-Hant-TW에는 zh-Hant, zh, en 순서의 폴백 체인을 적용해요.

흔한 실수

레거시 모드와 Composition API 모드 혼용

legacy: true(기본값)에서 useI18n()을 사용하면 오류가 발생해요. Composition API를 사용한다면 createI18n()에서 legacy: false를 설정하거나 Options API 템플릿의 $t()만 사용하세요. 한 애플리케이션에서 두 모드를 섞지 마세요.

번역 문자열에 v-html 사용

보간 값이 사용자 입력에서 온 경우 HTML이 포함된 번역을 v-html로 렌더링하면 XSS 위험이 있어요. HTML 또는 Vue 컴포넌트가 삽입된 번역에는 &lt;i18n-t&gt; 컴포넌트를 사용하세요. 기본적으로 안전하며 반응형 컴포넌트 삽입을 지원해요.

지역 사용자에게 상위 로케일 대신 영어가 표시됨

vue-i18n의 fallbackLocale은 로케일별 체인이 아닌 평면 목록이에요. pt-BR은 pt-PT를 완전히 건너뛰고 목록의 로케일(보통 'en')로 대체해요. vue-i18n-locale-chain을 사용해 딥 머지 방식의 올바른 지역 폴백를 추가하세요.

지금 i18n Agent 사용해 보기

번역 파일을 여기에 드롭

JSON, YAML, PO, XML, CSV, Markdown, Properties

또는 클릭하여 파일 선택

대상 언어

가입 불필요즉시 견적

Vue i18n FAQ