How Internationalization (i18n) is Implemented in Vue Color Avatar: A Complete Technical Guide

Vue Color Avatar implements internationalization using vue-i18n with a centralized instance configured in src/i18n/index.ts, locale bundles stored in src/i18n/locales/, and the useI18n composable providing the t function to components for type-safe translations.

Vue Color Avatar is an open-source avatar generator built with Vue 3 and TypeScript. Understanding how internationalization (i18n) is implemented in this project reveals a clean, scalable pattern for managing multilingual Vue applications that leverages automatic browser language detection and type-safe translation keys.

Architecture of the i18n Implementation

The internationalization layer follows a centralized pattern consisting of three coordinated parts: locale definition files containing translation mappings, a central i18n instance that configures vue-i18n with browser language detection, and component-level integration via the Composition API.

Configuring the i18n Instance

The core configuration resides in src/i18n/index.ts. This file creates the vue-i18n instance using createI18n, imports locale bundles for English and Chinese, and implements automatic language detection based on window.navigator.language.

// src/i18n/index.ts
import { createI18n } from 'vue-i18n'
import { Locale } from '@/enums'
import { en } from './locales/en'
import { zh } from './locales/zh'

const messages = { en, zh }

// Detect the user's language; fall back to the opposite language.
const [locale, fallbackLocale] = /^zh\b/.test(window.navigator.language)
  ? [Locale.ZH, Locale.EN]
  : [Locale.EN, Locale.ZH]

export const i18n = createI18n({
  locale,
  fallbackLocale,
  messages,
})

The detection logic uses the regex /^zh\b/ to test if the browser language starts with "zh". When matched, the application sets the locale to Chinese (Locale.ZH) with English as the fallback; otherwise, it defaults to English with Chinese as the fallback.

Organizing Locale Bundles

Translation strings are organized by language in src/i18n/locales/. Each locale exports a TypeScript object with nested keys corresponding to UI sections, ensuring type safety and maintainability.

// src/i18n/locales/en/index.ts
export const en = {
  action: {
    undo: 'undo',
    redo: 'redo',
    random: 'random',
    download: 'download',
    code: 'code',
  },
  label: {
    wrapperShape: 'Wrapper Shape',
    backgroundColor: 'Background Color',
  },
  widgetType: {
    [WidgetType.Face]: 'Face',
    [WidgetType.Eyes]: 'Eyes',
    [WidgetType.Eyebrows]: 'Eyebrows',
    // ... additional widget types
  },
}
// src/i18n/locales/zh/index.ts
export const zh = {
  action: {
    undo: '撤销',
    redo: '还原',
    random: '随机',
    download: '下载',
    code: '代码',
  },
  label: {
    wrapperShape: '头像框形状',
    backgroundColor: '背景颜色',
  },
  widgetType: {
    [WidgetType.Face]: '脸蛋',
    [WidgetType.Eyes]: '眼睛',
    [WidgetType.Eyebrows]: '眉毛',
    // ... additional widget types
  },
}

Both locale files import the WidgetType enum from src/enums/index.ts, using computed property names to ensure that widget-specific translation keys remain synchronized with the application's type definitions.

Registering and Using Translations in Components

The i18n instance is registered globally in src/main.ts using app.use(i18n), making translation utilities available throughout the application.

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

const app = createApp(App)

app.use(i18n)   // Makes $t and useI18n available globally
app.mount('#app')

Inside Vue Single File Components, the useI18n composable from vue-i18n provides the t function for resolving translation keys.

<!-- Example from src/components/ActionBar.vue -->
<script setup lang="ts">
import { useI18n } from 'vue-i18n'

const { t } = useI18n()
</script>

<template>
  <div class="action-bar">
    <button @click="handleUndo">
      {{ t('action.undo') }}   <!-- Renders "undo" or "撤销" -->
    </button>
    <button @click="handleRedo">
      {{ t('action.redo') }}
    </button>
    <button @click="handleRandom">
      {{ t('action.random') }}
    </button>
  </div>
</template>

This pattern appears consistently across components including Configurator.vue, DownloadModal.vue, and CodeModal.vue. Translation keys follow dot-notation paths such as t('action.undo'), t('label.wrapperShape'), or t('widgetType.Eyes'), corresponding to the nested structure of the locale bundles.

Extending the i18n Implementation to New Languages

Adding support for additional languages requires three steps:

  1. Create a new locale file at src/i18n/locales/<code>/index.ts (e.g., es for Spanish) that mirrors the structure of the existing English and Chinese bundles.

  2. Register the locale in src/i18n/index.ts by importing the new bundle and adding it to the messages object.

  3. Update the detection logic or provide a UI language switcher. Add the new language to the Locale enum in src/enums/index.ts if using TypeScript strict typing.

// src/enums/index.ts
export const enum Locale {
  ZH = 'zh',
  EN = 'en',
  ES = 'es',   // New language
}

To switch locales programmatically at runtime:

// Inside any component
import { useI18n } from 'vue-i18n'

const { locale } = useI18n()

function setLanguage(lang: string) {
  locale.value = lang      // e.g., 'zh', 'en', or 'es'
}

Summary

  • Vue Color Avatar implements internationalization using vue-i18n with a centralized configuration pattern in src/i18n/index.ts.
  • The application automatically detects browser language using navigator.language with regex matching (/^zh\b/) and implements a fallback strategy between English and Chinese.
  • Translation bundles are organized as TypeScript objects in src/i18n/locales/, using nested keys and WidgetType enum references for type safety.
  • Components access translations via the useI18n composable, calling the t function with dot-notation keys like t('action.undo').
  • The architecture supports easy extension to additional languages by creating new locale files and registering them in the central i18n configuration.

Frequently Asked Questions

What i18n library does Vue Color Avatar use?

Vue Color Avatar uses vue-i18n (version 9.x for Vue 3 compatibility) to handle all internationalization needs. This library provides the createI18n factory function for instance creation and the useI18n composable for accessing translation functions within components.

How does Vue Color Avatar detect the user's language?

The application detects language automatically in src/i18n/index.ts by testing window.navigator.language against the regex /^zh\b/. If the browser language starts with "zh" (Chinese), the application sets the active locale to Chinese with English as fallback; otherwise, it defaults to English with Chinese as fallback.

Can I add a third language to Vue Color Avatar?

Yes. To add a new language, create a TypeScript file under src/i18n/locales/<code>/index.ts that exports a message object matching the structure of the existing English and Chinese bundles. Import this file in src/i18n/index.ts, add it to the messages object, and update the Locale enum in src/enums/index.ts to include the new language code.

How are translation keys organized in Vue Color Avatar?

Translation keys follow a dot-notation hierarchy organized by UI section. Top-level keys include action (for buttons like undo/redo), label (for form labels), and widgetType (for avatar component names). The widgetType keys use computed property names from the WidgetType enum to ensure type safety and synchronization between translation files and application types.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →