# How to Enable Internationalization (i18n) in Apache ECharts for Multi-Language Support

> Enable ECharts internationalization i18n for multi-language support by registering locale files. Learn how to apply translations easily for global audiences.

- Repository: [The Apache Software Foundation/echarts](https://github.com/apache/echarts)
- Tags: how-to-guide
- Published: 2026-03-04

---

**To enable internationalization in ECharts, load a locale file that calls `echarts.registerLocale()`, then initialize your chart with `echarts.init(dom, theme, {locale: 'XX'})` to apply translations for toolbox labels, legends, time formats, and ARIA accessibility strings.**

Apache ECharts ships with a dedicated i18n subsystem that allows you to switch the UI language at initialization time or runtime. The library pre-bundles English and Chinese locales while providing an extension mechanism to register custom languages. All localization logic is centralized in [`src/core/locale.ts`](https://github.com/apache/echarts/blob/main/src/core/locale.ts) and consumed throughout the codebase via the instance's locale model.

## How the ECharts i18n Architecture Works

The internationalization system consists of a registry-based storage layer, default locale fallbacks, and instance-specific configuration bindings.

### The Locale Registry

ECharts exposes the `registerLocale` function in [`src/core/locale.ts`](https://github.com/apache/echarts/blob/main/src/core/locale.ts) (lines 45-49) to store locale definitions. When you call `echarts.registerLocale('FR', localeObj)`, the system:

1. Stores the definition in an internal `localeStorage` map
2. Creates a `Model` instance for fast property lookup
3. Merges the custom locale with the default English fallback via `createLocaleObject` (lines 55-66)

This merge strategy ensures that missing keys in your custom locale automatically fall back to English, preventing undefined strings in the UI.

### Default and Built-in Locales

By default, ECharts automatically registers two languages in [`src/core/locale.ts`](https://github.com/apache/echarts/blob/main/src/core/locale.ts) (lines 78-80):

- **English (`langEN`)** – Used as the `SYSTEM_LANG` fallback
- **Chinese (`langZH`)** – Available for Simplified Chinese interfaces

Additional official languages live in the `i18n/` directory (e.g., [`i18n/langFR.js`](https://github.com/apache/echarts/blob/main/i18n/langFR.js) for French). These files are auto-generated UMD wrappers that call `registerLocale` upon loading.

### Instance-Level Locale Binding

When you call `echarts.init()`, the initialization options accept a `locale` parameter defined in [`src/core/echarts.ts`](https://github.com/apache/echarts/blob/main/src/core/echarts.ts) (lines 55-57). You can pass either:

- A **string language code** (e.g., `'FR'`, `'DE'`) that references a pre-registered locale
- A **full locale object** containing translation keys for immediate use

The chosen locale is stored in the instance property `this._locale` and accessible throughout components via `model.ecModel.getLocaleModel()`, as seen in [`src/coord/axisHelper.ts`](https://github.com/apache/echarts/blob/main/src/coord/axisHelper.ts) (line 211) and calendar rendering logic.

## Loading and Registering Locale Files

Before initializing a chart, you must load the locale definition so it exists in the registry.

### Using CDN (UMD) Scripts

Include the locale file after the main ECharts bundle. The UMD file automatically registers itself:

```html
<script src="https://cdn.jsdelivr.net/npm/echarts@latest/dist/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@latest/dist/i18n/langFR.js"></script>

```

The French locale file ([`i18n/langFR.js`](https://github.com/apache/echarts/blob/main/i18n/langFR.js), lines 44-48) executes `echarts.registerLocale('FR', {...})` upon load, making the locale immediately available.

### ES Module Imports

For bundler-based projects, import the locale to trigger registration:

```javascript
import * as echarts from 'echarts';
import 'echarts/i18n/langDE';  // Side-effect: registers 'DE' locale

```

## Initializing Charts with a Specific Locale

Pass the `locale` option as the third argument to `echarts.init()`:

```javascript
// Using a pre-registered language code
const chart = echarts.init(
  document.getElementById('main'), 
  null, 
  { locale: 'FR' }
);

chart.setOption({
  title: { text: 'Statistiques des ventes' },
  toolbox: {
    feature: {
      saveAsImage: { title: 'Enregistrer' }
    }
  }
});

```

Alternatively, pass a complete locale object directly without pre-registering:

```javascript
const customLocale = {
  time: {
    month: ['January', 'February', 'March', 'April', 'May', 'June',
            'July', 'August', 'September', 'October', 'November', 'December']
  },
  legend: {
    selector: { all: 'All', inverse: 'Inv' }
  }
};

const chart = echarts.init(dom, null, { locale: customLocale });

```

## Runtime Locale Switching

Because the locale is bound to the **chart instance** at construction, you cannot change it dynamically via `setOption()`. To switch languages after rendering, dispose the instance and re-initialize:

```javascript
// Switch from current locale to English
function switchToEnglish() {
  const option = chart.getOption();
  chart.dispose();
  
  const newChart = echarts.init(
    document.getElementById('chart-container'), 
    null, 
    { locale: 'EN' }
  );
  
  newChart.setOption(option);
}

```

This pattern is necessary because components like axis helpers and calendar views read the locale model during initialization, not during updates.

## Creating Custom Locales for Unsupported Languages

Define a locale object following the ECharts locale schema, then register it at runtime:

```javascript
// myKoreanLocale.js
export const koLocale = {
  time: {
    month: ['1월','2월','3월','4월','5월','6월',
            '7월','8월','9월','10월','11월','12월'],
    monthAbbr: ['1월','2월','3월','4월','5월','6월',
                '7월','8월','9월','10월','11월','12월'],
    dayOfWeek: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'],
    dayOfWeekAbbr: ['일','월','화','수','목','금','토']
  },
  legend: { 
    selector: { all: '전체', inverse: '역' } 
  },
  toolbox: {
    brush: {
      title: {
        rect: '사각형 선택',
        polygon: '올가미 선택',
        lineX: '가로 선택',
        lineY: '세로 선택',
        keep: '선택 유지',
        clear: '선택 지우기'
      }
    }
  }
};

// app.js
import * as echarts from 'echarts';
import { koLocale } from './myKoreanLocale.js';

echarts.registerLocale('KO', koLocale);
const chart = echarts.init(dom, null, { locale: 'KO' });

```

Missing keys in your custom locale automatically inherit from the English default via the `createLocaleObject` merge logic in [`src/core/locale.ts`](https://github.com/apache/echarts/blob/main/src/core/locale.ts).

## Summary

- **Register locales** using `echarts.registerLocale(code, obj)` before initialization, or pass a locale object directly to `echarts.init()`.
- **Initialize with locale** by providing `{locale: 'CODE'}` as the third argument to `echarts.init(dom, theme, opts)`.
- **Fallback mechanism** ensures that partially defined locales merge with the built-in English defaults.
- **Runtime changes** require calling `dispose()` on the existing instance and re-initializing with the new locale code.
- **File locations**: Core logic resides in [`src/core/locale.ts`](https://github.com/apache/echarts/blob/main/src/core/locale.ts), built-in locales live in [`i18n/langXX.js`](https://github.com/apache/echarts/blob/main/i18n/langXX.js), and consumption occurs in components like [`src/coord/axisHelper.ts`](https://github.com/apache/echarts/blob/main/src/coord/axisHelper.ts) and [`src/component/calendar/CalendarView.ts`](https://github.com/apache/echarts/blob/main/src/component/calendar/CalendarView.ts).

## Frequently Asked Questions

### Can I change the ECharts locale without destroying the chart instance?

No. The locale is bound to the instance during construction in [`src/core/echarts.ts`](https://github.com/apache/echarts/blob/main/src/core/echarts.ts). To switch languages, you must call `chart.dispose()`, then `echarts.init()` with the new `locale` option, and finally `setOption()` to restore your configuration. This is the only supported pattern for runtime language switching.

### Which languages are officially supported by ECharts?

Apache ECharts officially bundles English (`EN`) and Chinese (`ZH`) in the core distribution. Additional community-contributed locales are available in the `i18n/` directory of the repository, including French (`FR`), German (`DE`), and others. You can view the full list of available locale files in the GitHub repository under the `i18n/` path.

### How do I add translations for an unsupported language?

Create a JavaScript object containing the translation keys for `time`, `legend`, `toolbox`, and other UI components, then call `echarts.registerLocale('XX', yourLocaleObject)` before initializing any charts. Your locale will merge with the English defaults, so you only need to specify keys that differ from the base language.

### Does ECharts support RTL (right-to-left) languages through the i18n system?

The i18n subsystem handles text content translation only (strings for labels, tooltips, and ARIA attributes). For RTL layout support (e.g., Arabic or Hebrew), you must configure the chart's positioning and axis direction manually using the standard ECharts option set, as the locale registry does not automatically flip coordinate systems or text alignment directions.