# How AionUI's Translation System Supports Multi-Language Localization (en-US, zh-CN, ja-JP)

> Discover how AionUi's translation system leverages i18next for seamless multi-language localization supporting en-US, zh-CN, and ja-JP with runtime detection and instant switching.

- Repository: [OfficeAI/AionUi](https://github.com/iofficeai/aionui)
- Tags: deep-dive
- Published: 2026-02-16

---

**AionUI uses the i18next ecosystem to share JSON translation bundles between the React renderer and Electron main process, enabling runtime language detection and instant switching for locales including en-US, zh-CN, and ja-JP.**

The iOfficeAI/AionUi repository implements a robust internationalization (i18n) architecture that keeps all UI strings in centralized JSON files. This design allows the application to support multiple languages without code duplication, using the same translation keys across both frontend components and backend error dialogs.

## Locale Bundle Architecture

AionUI stores all translatable content as static JSON resources, creating a single source of truth for text content.

### JSON File Organization

Translation files live in `src/renderer/i18n/locales/` and follow the BCP-47 naming convention. Each file exports a flat or nested object where keys represent translation identifiers and values contain the localized text.

The repository includes dedicated bundles for:

- [`en-US.json`](https://github.com/iOfficeAI/AionUi/blob/main/en-US.json) – English (United States)
- [`zh-CN.json`](https://github.com/iOfficeAI/AionUi/blob/main/zh-CN.json) – Simplified Chinese
- [`ja-JP.json`](https://github.com/iOfficeAI/AionUi/blob/main/ja-JP.json) – Japanese

### Key-Based Design

All UI elements, error messages, and configuration labels use stable dot-notation keys (e.g., `settings.platformCustom`, `codex.network.timeout_title`). This structure decouples the code from specific languages, allowing new locales to be added by simply creating a JSON file with identical keys.

## Renderer Process Implementation

The React frontend initializes i18next in [`src/renderer/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/renderer/i18n/index.ts), creating a shared instance that supports automatic language detection and React integration.

### i18next Initialization

The configuration imports locale JSON files directly and registers them as translation resources:

```typescript
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
import enUS from './locales/en-US.json';
import zhCN from './locales/zh-CN.json';
import jaJP from './locales/ja-JP.json';

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    resources: {
      'en-US': { translation: enUS },
      'zh-CN': { translation: zhCN },
      'ja-JP': { translation: jaJP },
    },
    fallbackLng: 'en-US',
    debug: false,
    interpolation: { escapeValue: false },
  });

```

This file is imported early in [`src/renderer/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/renderer/index.ts) via `import './i18n';`, ensuring the translation system is ready before any components render.

### Language Detection and Switching

The `i18next-browser-languagedetector` plugin automatically inspects `navigator.language`, localStorage, and query parameters to determine the initial locale. If detection fails or the locale is unsupported, the system falls back to `en-US`.

Programmatic switching is handled via the `changeLanguage` method:

```typescript
i18n.changeLanguage('zh-CN');

```

This updates the active locale instantly and triggers re-renders in all React components using the `useTranslation` hook.

## Main Process Integration

The Electron main process requires the same translations for native dialogs and background logic. AionUI mirrors the renderer setup in [`src/process/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/process/i18n/index.ts), importing the identical JSON bundles from the renderer directory and exposing a separate i18next instance.

Backend modules like [`CodexAgentManager.ts`](https://github.com/iOfficeAI/AionUi/blob/main/CodexAgentManager.ts) consume this instance directly:

```typescript
import i18n from '@process/i18n';

function showNetworkError() {
  const title = i18n.t('codex.network.timeout_title');
  const message = i18n.t('codex.network.recovery_suggestions');
  dialog.showErrorBox(title, message);
}

```

This architecture ensures consistent messaging across the UI and system-level error handlers without duplicating translation files.

## Consuming Translations in Components

AionUI provides ergonomic access to translations in both React and non-React contexts.

### React Hooks

Components use the `useTranslation` hook from `react-i18next` to access the `t` function and `i18n` instance:

```tsx
import { useTranslation } from 'react-i18next';

export default function SettingsPanel() {
  const { t, i18n } = useTranslation();

  return (
    <div>
      <h1>{t('settings.title')}</h1>
      <p>Current locale: {i18n.language}</p>
    </div>
  );
}

```

### Dynamic UI Elements

Platform configurations in [`src/renderer/config/modelPlatforms.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/renderer/config/modelPlatforms.ts) support an optional `i18nKey` field, allowing dynamic labels to be translated without hard-coding text:

```typescript
{
  id: 'openai',
  name: 'OpenAI',
  i18nKey: 'platform.openai.name',
  // ...
}

```

Components render these by passing the key to the `t` function, ensuring dropdowns and tooltips remain localizable.

## Adding New Languages

Extending AionUI to support additional languages requires minimal code changes:

1. Create a new JSON file in `src/renderer/i18n/locales/` using the BCP-47 identifier (e.g., [`ko-KR.json`](https://github.com/iOfficeAI/AionUi/blob/main/ko-KR.json) for Korean).

2. Copy the keys from an existing locale file and translate the values.

3. Import the new JSON in [`src/renderer/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/renderer/i18n/index.ts) and add it to the `resources` map:

```typescript
import koKR from './locales/ko-KR.json';

// Inside init configuration
resources: {
  'ko-KR': { translation: koKR },
  // existing locales...
}

```

4. Update any language selector UI to include the new option.

The same JSON file can be imported by [`src/process/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/process/i18n/index.ts) to ensure the main process recognizes the new locale immediately.

## Summary

- AionUI uses **i18next** with **react-i18next** to manage translations across the React renderer and Electron main process.
- Locale data resides in `src/renderer/i18n/locales/` as JSON files named with BCP-47 identifiers like [`en-US.json`](https://github.com/iOfficeAI/AionUi/blob/main/en-US.json), [`zh-CN.json`](https://github.com/iOfficeAI/AionUi/blob/main/zh-CN.json), and [`ja-JP.json`](https://github.com/iOfficeAI/AionUi/blob/main/ja-JP.json).
- The `i18next-browser-languagedetector` plugin automatically detects the user's language, falling back to `en-US` when necessary.
- Both renderer and main processes share the same translation keys, ensuring consistent messaging in UI components and native dialogs.
- Adding a new language requires only creating a JSON file and registering it in [`src/renderer/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/renderer/i18n/index.ts).

## Frequently Asked Questions

### What i18n library does AionUI use?

AionUI uses **i18next** together with **react-i18next** for the React renderer and **i18next-browser-languagedetector** for automatic language detection. The Electron main process uses a separate i18next instance initialized in [`src/process/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/process/i18n/index.ts) that imports the same JSON locale files.

### How does AionUI detect the user's language?

The system relies on the `i18next-browser-languagedetector` plugin, which checks the browser's `navigator.language`, localStorage preferences, and URL query parameters. If detection fails or returns an unsupported locale, AionUI falls back to `en-US` as defined in the `fallbackLng` configuration option in [`src/renderer/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/renderer/i18n/index.ts).

### Can I add a custom locale without modifying core files?

While you must edit [`src/renderer/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/renderer/i18n/index.ts) to import the new JSON file and add it to the `resources` map, the process is non-breaking and follows a simple pattern. Create your locale file in `src/renderer/i18n/locales/`, import it, and register it under the appropriate BCP-47 key. The main process will automatically support the new locale if it imports the same file.

### Does the main process share the same translation files as the renderer?

Yes. The main process configuration in [`src/process/i18n/index.ts`](https://github.com/iOfficeAI/AionUi/blob/main/src/process/i18n/index.ts) imports the JSON files directly from the renderer's `src/renderer/i18n/locales/` directory. This ensures that error dialogs and background logic use the exact same keys and translations as the UI, maintaining consistency across the entire application.