Skip to content

Internationalization (i18n)

YH-UI provides comprehensive internationalization (i18n) support, featuring 67 built-in language packs covering major global languages and regions. You can configure the global language via the YhConfigProvider component or use the useLocale Hook within components for fine-grained control.

Basic Usage

Set the global language pack using the locale property of YhConfigProvider. If not set, it defaults to Simplified Chinese (zh-cn).

March 2026
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
Basic Usage

Multi-language Switching

YH-UI includes 67 built-in language packs. You can dynamically switch to any language using a dropdown selector.

en
Current Language: en
March 2026
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
Multi-language Switching

Built-in Language Packs

YH-UI has 67 built-in language packs, covering major global languages and regions:

Chinese

LanguageLanguage CodeImport NameNative Name
Simplified Chinesezh-cnzhCnSimplified Chinese
Traditional Chinese (Taiwan)zh-twzhTwTraditional Chinese
Traditional Chinese (Hong Kong)zh-hkzhHkTraditional Chinese
Traditional Chinese (Macau)zh-mozhMoTraditional Chinese

East Asian Languages

LanguageLanguage CodeImport NameNative Name
JapanesejajaJapanese
KoreankokoKorean
MongolianmnmnMongolian

Southeast Asian Languages

LanguageLanguage CodeImport NameNative Name
ThaiththThai
VietnameseviviVietnamese
IndonesianididIndonesian
MalaymsmsMalay
BurmesemymyBurmese
Khmer (Cambodia)kmkmKhmer
LaololoLao

South Asian Languages

LanguageLanguage CodeImport NameNative Name
HindihihiHindi
PunjabipapaPunjabi
BengalibnbnBengali
TamiltataTamil
TeluguteteTelugu

West European Languages

LanguageLanguage CodeImport NameNative Name
EnglishenenEnglish
GermandedeDeutsch
FrenchfrfrFrançais
SpanishesesEspañol
PortugueseptptPortuguês
Portuguese (Brazil)pt-brptBrPortuguês (Brasil)
ItalianititItaliano
DutchnlnlNederlands
CatalancacaCatalan
BasqueeueuBasque

North European Languages

LanguageLanguage CodeImport NameNative Name
DanishdadaDansk
SwedishsvsvSvenska
FinnishfifiSuomi
NorwegiannonoNorsk
Norwegian Bokmålnb-NOnbNoNorsk Bokmål

East European Languages

LanguageLanguage CodeImport NameNative Name
RussianruruРусский
UkrainianukukУкраїнська
PolishplplPolski
CzechcscsČeština
SlovakskskSlovenčina
HungarianhuhuMagyar
Romanianro`ro"Română
BulgarianbgbgБългарски
SerbiansrsrСрпски
CroatianhrhrHrvatski
SlovenianslslSlovenščina
EstonianetetEesti
LatvianlvlvLatviešu
LithuanianltltLietuvių

Middle East / West Asian Languages

LanguageLanguage CodeImport NameNative Name
ArabicararArabic
Arabic (Egypt)ar-egarEgArabic (Egypt)
TurkishtrtrTurkish
PersianfafaPersian
HebrewheheHebrew
Armenianhy-amhyAmArmenian
AzerbaijaniazazAzerbaijani
GreekelelGreek

Central Asian Languages

LanguageLanguage CodeImport NameNative Name
KazakhkkkkKazakh
KyrgyzkykyKyrgyz
TurkmentktkTurkmen
Uzbekuz-uzuzUzUzbek
Uyghurug-cnugCnUyghur
Kurdish (Northern)kukuKurdish (Northern)
Kurdish (Central)ckbckbKurdish (Central)

African Languages

LanguageLanguage CodeImport NameNative Name
AfrikaansafafAfrikaans
SwahiliswswKiswahili
MalagasymgmgMalagasy

Artificial Languages

LanguageLanguage CodeImport NameNative Name
EsperantoeoeoEsperanto

Import examples:

ts
// Import a single language pack
import { zhCn, en, ja, ko, fr, de } from '@yh-ui/locale'

// Import all language packs
import * as locales from '@yh-ui/locale'

Global Configuration

Usage in Vue 3

Wrap the root component with YhConfigProvider at the application entry point:

vue
<!-- App.vue -->
<script setup lang="ts">
import { ref } from 'vue'
import { en, zhCn } from '@yh-ui/locale'

// Can be set dynamically based on user preference or browser language
const locale = ref(zhCn)
</script>

<template>
  <YhConfigProvider :locale="locale">
    <router-view />
  </YhConfigProvider>
</template>

Usage in Nuxt 3

Configure within app.vue:

vue
<!-- app.vue -->
<script setup lang="ts">
import { zhCn } from '@yh-ui/locale'
</script>

<template>
  <YhConfigProvider :locale="zhCn">
    <NuxtPage />
  </YhConfigProvider>
</template>

Dynamic Language Switching

vue
<script setup lang="ts">
import { ref, computed } from 'vue'
import { zhCn, en, ja, ko, fr, de } from '@yh-ui/locale'

// Language mapping table
const localeMap = {
  'zh-cn': zhCn,
  'en': en,
  'ja': ja,
  'ko': ko,
  'fr': fr,
  'de': de
}

const currentLang = ref('zh-cn')
const currentLocale = computed(() => localeMap[currentLang.value] || zhCn)

// Switch language
const switchLanguage = (lang: string) => {
  currentLang.value = lang
}

// Automatically set based on browser language
const autoDetectLanguage = () => {
  const browserLang = navigator.language.toLowerCase()
  if (browserLang.startsWith('zh')) {
    currentLang.value = 'zh-cn'
  } else if (browserLang.startsWith('ja')) {
    currentLang.value = 'ja'
  } else if (browserLang.startsWith('ko')) {
    currentLang.value = 'ko'
  } else {
    currentLang.value = 'en'
  }
}
</script>

<template>
  <YhConfigProvider :locale="currentLocale">
    <div>
      <select v-model="currentLang">
        <option value="zh-cn">Chinese</option>
        <option value="en">English</option>
        <option value="ja">Japanese</option>
        <option value="ko">Korean</option>
        <option value="fr">French</option>
        <option value="de">German</option>
      </select>
    </div>
    <!-- Application content -->
  </YhConfigProvider>
</template>

Using the useLocale Hook

Within a component, use the useLocale Hook to retrieve translation functions and current language info:

vue
<script setup lang="ts">
import { useLocale } from '@yh-ui/hooks'

const { t, tRaw, lang, locale } = useLocale()

// Get string translation
const emptyText = t('table.emptyText') // 'No Data'

// Translation with interpolation
const totalText = t('pagination.total', { total: 100 }) // 'Total 100'

// Get raw translations for non-string types (e.g., arrays)
const rateTexts = tRaw<string[]>('rate.texts') // ['Terrible', 'Bad', 'Neutral', 'Good', 'Great']

// Current language code
console.log(lang.value) // 'zh-cn', 'en', etc.
</script>

useLocale Return Values

Property/MethodTypeDescription
localeComputedRef<Language>Current language pack object
langComputedRef<string>Current language code (e.g., 'zh-cn', 'en')
t(path: string, options?: Record<string, string | number>) => stringTranslation function with interpolation support
tRaw<T>(path: string) => TRetrieves raw translation values (supports arrays, etc.)

Custom Translations

Overriding Specific Translations

Modify or supplement specific translation items by extending an existing language pack:

ts
import { zhCn } from '@yh-ui/locale'
import type { Language } from '@yh-ui/locale'

const customZhCn: Language = {
  ...zhCn,
  yh: {
    ...zhCn.yh,
    table: {
      ...zhCn.yh.table,
      emptyText: 'Nothing here yet~',
      loading: 'Loading data, please wait...'
    },
    pagination: {
      ...zhCn.yh.pagination,
      total: 'Total {total} records'
    }
  }
}

Creating New Language Packs

If additional language support is needed, refer to the structure of existing language packs:

ts
import type { Language } from '@yh-ui/locale'

export const myLang: Language = {
  name: 'my-lang',
  yh: {
    common: {
      yes: 'Yes',
      no: 'No',
      confirm: 'Confirm',
      cancel: 'Cancel',
      loading: 'Loading',
      close: 'Close',
      clear: 'Clear',
      reset: 'Reset',
      save: 'Save',
      delete: 'Delete',
      edit: 'Edit',
      add: 'Add',
      search: 'Search',
      refresh: 'Refresh',
      expand: 'Expand',
      collapse: 'Collapse',
      more: 'More',
      noData: 'No Data',
      noMatch: 'No matching data',
      selectAll: 'Select All',
      unselectAll: 'Unselect All'
    },
    // ... component translations
  }
}

Language Pack Structure

YH-UI language packs use a flattened namespace structure. Each component has its own set of translation keys.

Common (common)

ts
common: {
  yes: 'Yes',
  no: 'No',
  confirm: 'Confirm',
  cancel: 'Cancel',
  loading: 'Loading',
  close: 'Close',
  clear: 'Clear',
  reset: 'Reset',
  save: 'Save',
  delete: 'Delete',
  edit: 'Edit',
  add: 'Add',
  search: 'Search',
  refresh: 'Refresh',
  expand: 'Expand',
  collapse: 'Collapse',
  more: 'More',
  noData: 'No Data',
  noMatch: 'No matching data',
  selectAll: 'Select All',
  unselectAll: 'Unselect All'
}

Table (table)

ts
table: {
  emptyText: 'No Data',
  confirmFilter: 'Filter',
  resetFilter: 'Reset',
  clearFilter: 'All',
  sumText: 'Sum',
  loading: 'Loading...',
  index: 'Index',
  print: 'Print',
  cancel: 'Cancel',
  preview: 'Print Preview',
  printTime: 'Print Time',
  total: 'Total {total}',
  page: 'Page {page}',
  yes: 'Yes',
  no: 'No',
  // Toolbar
  toolbar: {
    refresh: 'Refresh',
    density: 'Density',
    densityDefault: 'Default',
    densityLarge: 'Loose',
    densitySmall: 'Compact',
    columnSetting: 'Column Settings',
    fullscreen: 'Fullscreen',
    exitFullscreen: 'Exit Fullscreen',
    export: 'Export',
    import: 'Import',
    search: 'Search',
    searchPlaceholder: 'Search...'
  },
  // Filtering
  filter: {
    selectAll: 'Select All',
    selectInvert: 'Invert Selection',
    empty: 'Empty',
    notEmpty: 'Not Empty',
    contains: 'Contains',
    notContains: 'Does Not Contain',
    equals: 'Equals',
    notEquals: 'Does Not Equal',
    startsWith: 'Starts With',
    endsWith: 'Ends With',
    greaterThan: 'Greater Than',
    lessThan: 'Less Than',
    between: 'Between'
  },
  // Sorting
  sort: {
    asc: 'Ascending',
    desc: 'Descending',
    clear: 'Cancel Sorting'
  },
  // Exporting
  export: {
    title: 'Export Data',
    filename: 'Filename',
    type: 'File Type',
    scope: 'Export Scope',
    scopeAll: 'All Data',
    scopeSelected: 'Selected Data',
    scopeCurrentPage: 'Current Page Data',
    includeHeader: 'Include Header',
    exporting: 'Exporting...',
    success: 'Export Successful',
    error: 'Export Failed'
  },
  // Importing
  import: {
    title: 'Import Data',
    selectFile: 'Select File',
    dragTip: 'Click or drag file here to upload',
    importing: 'Importing...',
    success: 'Import Successful',
    error: 'Import Failed',
    preview: 'Data Preview',
    confirm: 'Confirm Import'
  },
  // Print Configuration
  printConfig: {
    title: 'Print Settings',
    pageTitle: 'Page Title',
    pageHeader: 'Page Header',
    pageFooter: 'Page Footer',
    printAll: 'Print All',
    printSelected: 'Print Selected',
    printCurrentPage: 'Print Current Page',
    landscape: 'Landscape',
    portrait: 'Portrait',
    printing: 'Printing...'
  },
  // Column Settings
  columnSetting: {
    title: 'Column Settings',
    showAll: 'Show All',
    hideAll: 'Hide All',
    reset: 'Reset',
    fixedLeft: 'Fixed Left',
    fixedRight: 'Fixed Right',
    unfixed: 'Unfixed'
  },
  // Context Menu
  contextMenu: {
    copy: 'Copy',
    copyRow: 'Copy Row',
    copyCell: 'Copy Cell',
    paste: 'Paste',
    insertRowAbove: 'Insert Row Above',
    insertRowBelow: 'Insert Row Below',
    deleteRow: 'Delete Row',
    deleteSelectedRows: 'Delete Selected Rows',
    exportSelected: 'Export Selected Data'
  },
  // Selection
  selection: {
    selectAll: 'Select All',
    selectInvert: 'Invert Selection',
    selectNone: 'Unselect All',
    selected: 'Selected {count} items'
  },
  // Expanding
  expand: {
    expandAll: 'Expand All',
    collapseAll: 'Collapse All'
  },
  // Tree
  tree: {
    expandAll: 'Expand All',
    collapseAll: 'Collapse All',
    expandLevel: 'Expand to level {level}'
  },
  // Dragging
  drag: {
    dragTip: 'Drag to reorder',
    dropTip: 'Release to drop'
  }
}

Date Picker (datepicker)

ts
datepicker: {
  now: 'Now',
  today: 'Today',
  cancel: 'Cancel',
  clear: 'Clear',
  confirm: 'Confirm',
  selectDate: 'Select Date',
  selectTime: 'Select Time',
  startDate: 'Start Date',
  startTime: 'Start Time',
  endDate: 'End Date',
  endTime: 'End Time',
  year: 'Year',
  month: 'Month',
  day: 'Day',
  week: 'Week',
  prevYear: 'Previous Year',
  nextYear: 'Next Year',
  prevMonth: 'Previous Month',
  nextMonth: 'Next Month',
  weeks: {
    sun: 'Sun', mon: 'Mon', tue: 'Tue', wed: 'Wed',
    thu: 'Thu', fri: 'Fri', sat: 'Sat'
  },
  months: {
    jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr',
    may: 'May', jun: 'Jun', jul: 'Jul', aug: 'Aug',
    sep: 'Sep', oct: 'Oct', nov: 'Nov', dec: 'Dec'
  },
  quarters: {
    q1: 'Q1', q2: 'Q2', q3: 'Q3', q4: 'Q4'
  }
}

Other Components

Click to expand the full list of component translation keys
ComponentNamespaceKey Translation Keys
Time Pickertimepickerconfirm, cancel, now, placeholder, startPlaceholder, endPlaceholder
Time Selecttimeselectplaceholder
CalendarcalendarprevMonth, nextMonth, today, week, holiday, workday, weeks.*
Selectselectplaceholder, noData, loading, noMatch, selectAll, clearAll
Cascadercascaderplaceholder, noData, loading, noMatch
Tree Selecttreeselectplaceholder, emptyText, loading, noMatch
Transfertransfertitles, filterPlaceholder, noData, noMatch, noCheckedFormat, hasCheckedFormat
Inputinputplaceholder, clear, showPassword, hidePassword, copy, copied
Input Numberinputnumberplaceholder, increase, decrease
Input Taginputtagplaceholder, add, remove
Autocompleteautocompleteplaceholder, loading, noData, noMatch
Uploaduploadtip, dragTip, uploading, success, error, delete, preview
FormformvalidationFailed, required, pleaseInput, pleaseSelect
Paginationpaginationgoto, page, total, pageSize, prev, next, first, last
Dialogdialogconfirm, cancel, close, maximize, restore
Drawerdrawerclose, confirm, cancel
Message Boxmessageboxtitle, confirm, cancel, close, error
Messagemessageclose
Notificationnotificationclose
Popconfirmpopconfirmconfirm, cancel, dontAskAgain
Imageimageerror, loading, preview, zoomIn, zoomOut, rotateLeft, rotateRight
Infinite Scrollinfinitescrollloading, finished, error, retry
TreetreeemptyText, loading, checkAll, uncheckAll, expandAll, collapseAll
Color Pickercolorpickerconfirm, clear, eyeDropper, suggestionDark, suggestionLight
Rateratetexts (Array)
Countdowncountdowndays, hours, minutes, seconds, milliseconds, finished
Loadingspintext
Buttonbuttonloading
Breadcrumbbreadcrumblabel, more
Backtopbacktoptext
Dropdowndropdownloading
Emptyemptydescription, noData, noResult, networkError, serverError
Resultresultsuccess, error, warning, info, backHome

Integration with Third-party Libraries

Integration with vue-i18n

If your project uses vue-i18n, you can merge YH-UI's language packs into your vue-i18n configuration:

ts
import { createI18n } from 'vue-i18n'
import { zhCn, en } from '@yh-ui/locale'

const i18n = createI18n({
  locale: 'en',
  messages: {
    'zh-cn': {
      // Business translations
      hello: 'Hello',
      // Merge YH-UI translations
      yh: zhCn.yh
    },
    'en': {
      hello: 'Hello',
      yh: en.yh
    }
  }
})

Create a reactive language pack:

ts
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import type { Language } from '@yh-ui/locale'

export function useYhLocale() {
  const { locale, messages } = useI18n()
  
  return computed<Language>(() => ({
    name: locale.value,
    yh: messages.value[locale.value].yh
  }))
}

TypeScript Support

YH-UI language packs include full TypeScript type definitions. Use the Language type for type hinting:

ts
import type { Language } from '@yh-ui/locale'

// Comprehensive type hinting when creating custom language packs
const customLocale: Language = {
  name: 'custom',
  yh: {
    // TypeScript will prompt for all required properties
  }
}

Contributing Translations

If you find a translation error or wish to add support for a new language, feel free to submit a Pull Request.

Language pack files are located in the packages/locale/src/lang directory. You can refer to the existing zh-cn.ts and en.ts for implementation.

Contribution Steps

  1. Fork the repository.
  2. Create a new language file (e.g., new-lang.ts) in the packages/locale/src/lang directory.
  3. Complete all translations based on the structure of zh-cn.ts.
  4. Export the new language pack in packages/locale/src/index.ts.
  5. Submit a Pull Request.

Frequently Asked Questions

Why is text in some components not translated?

Ensure that:

  1. The application is correctly wrapped with YhConfigProvider.
  2. The locale property passed is reactive (using ref or computed).
  3. The language pack contains the corresponding translation keys.

How to translate only specific components?

You can use nested YhConfigProvider components in specific areas:

vue
<template>
  <YhConfigProvider :locale="zhCn">
    <!-- These render in Chinese -->
    <YhTable />
    
    <YhConfigProvider :locale="en">
      <!-- This renders in English -->
      <YhPagination />
    </YhConfigProvider>
  </YhConfigProvider>
</template>

How to use interpolation variables in translations?

Certain translations contain interpolation variables (e.g., {total}, {count}), which are replaced at runtime:

ts
// Language pack definition
pagination: {
  total: 'Total {total}'
}

// Internal component usage
t('pagination.total', { total: 100 }) // Output: 'Total 100'

Released under the MIT License.