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).
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
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
YH-UI includes 67 built-in language packs. You can dynamically switch to any language using a dropdown selector.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
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 |
Built-in Language Packs
YH-UI has 67 built-in language packs, covering major global languages and regions:
Chinese
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Simplified Chinese | zh-cn | zhCn | Simplified Chinese |
| Traditional Chinese (Taiwan) | zh-tw | zhTw | Traditional Chinese |
| Traditional Chinese (Hong Kong) | zh-hk | zhHk | Traditional Chinese |
| Traditional Chinese (Macau) | zh-mo | zhMo | Traditional Chinese |
East Asian Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Japanese | ja | ja | Japanese |
| Korean | ko | ko | Korean |
| Mongolian | mn | mn | Mongolian |
Southeast Asian Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Thai | th | th | Thai |
| Vietnamese | vi | vi | Vietnamese |
| Indonesian | id | id | Indonesian |
| Malay | ms | ms | Malay |
| Burmese | my | my | Burmese |
| Khmer (Cambodia) | km | km | Khmer |
| Lao | lo | lo | Lao |
South Asian Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Hindi | hi | hi | Hindi |
| Punjabi | pa | pa | Punjabi |
| Bengali | bn | bn | Bengali |
| Tamil | ta | ta | Tamil |
| Telugu | te | te | Telugu |
West European Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| English | en | en | English |
| German | de | de | Deutsch |
| French | fr | fr | Français |
| Spanish | es | es | Español |
| Portuguese | pt | pt | Português |
| Portuguese (Brazil) | pt-br | ptBr | Português (Brasil) |
| Italian | it | it | Italiano |
| Dutch | nl | nl | Nederlands |
| Catalan | ca | ca | Catalan |
| Basque | eu | eu | Basque |
North European Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Danish | da | da | Dansk |
| Swedish | sv | sv | Svenska |
| Finnish | fi | fi | Suomi |
| Norwegian | no | no | Norsk |
| Norwegian Bokmål | nb-NO | nbNo | Norsk Bokmål |
East European Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Russian | ru | ru | Русский |
| Ukrainian | uk | uk | Українська |
| Polish | pl | pl | Polski |
| Czech | cs | cs | Čeština |
| Slovak | sk | sk | Slovenčina |
| Hungarian | hu | hu | Magyar |
| Romanian | ro | `ro" | Română |
| Bulgarian | bg | bg | Български |
| Serbian | sr | sr | Српски |
| Croatian | hr | hr | Hrvatski |
| Slovenian | sl | sl | Slovenščina |
| Estonian | et | et | Eesti |
| Latvian | lv | lv | Latviešu |
| Lithuanian | lt | lt | Lietuvių |
Middle East / West Asian Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Arabic | ar | ar | Arabic |
| Arabic (Egypt) | ar-eg | arEg | Arabic (Egypt) |
| Turkish | tr | tr | Turkish |
| Persian | fa | fa | Persian |
| Hebrew | he | he | Hebrew |
| Armenian | hy-am | hyAm | Armenian |
| Azerbaijani | az | az | Azerbaijani |
| Greek | el | el | Greek |
Central Asian Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Kazakh | kk | kk | Kazakh |
| Kyrgyz | ky | ky | Kyrgyz |
| Turkmen | tk | tk | Turkmen |
| Uzbek | uz-uz | uzUz | Uzbek |
| Uyghur | ug-cn | ugCn | Uyghur |
| Kurdish (Northern) | ku | ku | Kurdish (Northern) |
| Kurdish (Central) | ckb | ckb | Kurdish (Central) |
African Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Afrikaans | af | af | Afrikaans |
| Swahili | sw | sw | Kiswahili |
| Malagasy | mg | mg | Malagasy |
Artificial Languages
| Language | Language Code | Import Name | Native Name |
|---|---|---|---|
| Esperanto | eo | eo | Esperanto |
Import examples:
// 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:
<!-- 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:
<!-- app.vue -->
<script setup lang="ts">
import { zhCn } from '@yh-ui/locale'
</script>
<template>
<YhConfigProvider :locale="zhCn">
<NuxtPage />
</YhConfigProvider>
</template>Dynamic Language Switching
<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:
<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/Method | Type | Description |
|---|---|---|
locale | ComputedRef<Language> | Current language pack object |
lang | ComputedRef<string> | Current language code (e.g., 'zh-cn', 'en') |
t | (path: string, options?: Record<string, string | number>) => string | Translation function with interpolation support |
tRaw | <T>(path: string) => T | Retrieves raw translation values (supports arrays, etc.) |
Custom Translations
Overriding Specific Translations
Modify or supplement specific translation items by extending an existing language pack:
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:
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)
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)
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)
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
| Component | Namespace | Key Translation Keys |
|---|---|---|
| Time Picker | timepicker | confirm, cancel, now, placeholder, startPlaceholder, endPlaceholder |
| Time Select | timeselect | placeholder |
| Calendar | calendar | prevMonth, nextMonth, today, week, holiday, workday, weeks.* |
| Select | select | placeholder, noData, loading, noMatch, selectAll, clearAll |
| Cascader | cascader | placeholder, noData, loading, noMatch |
| Tree Select | treeselect | placeholder, emptyText, loading, noMatch |
| Transfer | transfer | titles, filterPlaceholder, noData, noMatch, noCheckedFormat, hasCheckedFormat |
| Input | input | placeholder, clear, showPassword, hidePassword, copy, copied |
| Input Number | inputnumber | placeholder, increase, decrease |
| Input Tag | inputtag | placeholder, add, remove |
| Autocomplete | autocomplete | placeholder, loading, noData, noMatch |
| Upload | upload | tip, dragTip, uploading, success, error, delete, preview |
| Form | form | validationFailed, required, pleaseInput, pleaseSelect |
| Pagination | pagination | goto, page, total, pageSize, prev, next, first, last |
| Dialog | dialog | confirm, cancel, close, maximize, restore |
| Drawer | drawer | close, confirm, cancel |
| Message Box | messagebox | title, confirm, cancel, close, error |
| Message | message | close |
| Notification | notification | close |
| Popconfirm | popconfirm | confirm, cancel, dontAskAgain |
| Image | image | error, loading, preview, zoomIn, zoomOut, rotateLeft, rotateRight |
| Infinite Scroll | infinitescroll | loading, finished, error, retry |
| Tree | tree | emptyText, loading, checkAll, uncheckAll, expandAll, collapseAll |
| Color Picker | colorpicker | confirm, clear, eyeDropper, suggestionDark, suggestionLight |
| Rate | rate | texts (Array) |
| Countdown | countdown | days, hours, minutes, seconds, milliseconds, finished |
| Loading | spin | text |
| Button | button | loading |
| Breadcrumb | breadcrumb | label, more |
| Backtop | backtop | text |
| Dropdown | dropdown | loading |
| Empty | empty | description, noData, noResult, networkError, serverError |
| Result | result | success, 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:
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:
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:
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
- Fork the repository.
- Create a new language file (e.g.,
new-lang.ts) in thepackages/locale/src/langdirectory. - Complete all translations based on the structure of
zh-cn.ts. - Export the new language pack in
packages/locale/src/index.ts. - Submit a Pull Request.
Frequently Asked Questions
Why is text in some components not translated?
Ensure that:
- The application is correctly wrapped with
YhConfigProvider. - The
localeproperty passed is reactive (usingreforcomputed). - The language pack contains the corresponding translation keys.
How to translate only specific components?
You can use nested YhConfigProvider components in specific areas:
<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:
// Language pack definition
pagination: {
total: 'Total {total}'
}
// Internal component usage
t('pagination.total', { total: 100 }) // Output: 'Total 100'