# How to Implement Internationalization with Multiple Language Support Using locale.use and locale.i18n in Element UI

> Learn to implement multi-language support in Element UI using locale.use for runtime switching and locale.i18n for custom translation handlers like vue-i18n. Enhance your app's global reach.

- Repository: [饿了么前端/element](https://github.com/ElemeFE/element)
- Tags: how-to-guide
- Published: 2026-03-07

---

**Use `locale.use()` to switch language packs at runtime and `locale.i18n()` to delegate translations to a custom handler like vue-i18n, enabling seamless multi-language support in Element UI components.**

Element UI provides a lightweight internationalization system through its locale module in the ElemeFE/element repository. By leveraging `locale.use` and `locale.i18n`, developers can implement internationalization with multiple language support either using built-in translations or integrating with external i18n libraries.

## Core Architecture of the Locale System

The internationalization layer is implemented across four key files that manage language state, component integration, and translation delegation.

| Component | Role | Important Export(s) |
|-----------|------|---------------------|
| **[`src/locale/index.js`](https://github.com/ElemeFE/element/blob/main/src/locale/index.js)** | Holds the current language object, provides the `t` function for string lookup, the `use` API to replace the language pack, and the `i18n` API to inject a custom translation handler. | `use`, `t`, `i18n` |
| **[`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js)** | The main entry point for the library. During `install`, it forwards the user‑provided `locale` and `i18n` options to the locale module. | `locale.use(opts.locale)`, `locale.i18n(opts.i18n)` |
| **[`src/mixins/locale.js`](https://github.com/ElemeFE/element/blob/main/src/mixins/locale.js)** | A Vue mixin that injects a component method `t` delegating to the locale module, so any component can call `this.t(...)` without importing the module directly. | `methods: { t(...args) { return t.apply(this, args) } }` |
| **`src/locale/lang/`** | Directory containing built‑in language packs (e.g., `en-US`, `zh-CN`, `ja-JP`). | Language objects |

## Using locale.use to Switch Language Packs

The `locale.use` function replaces the internal language table at runtime, causing all subsequent translation calls to resolve against the new pack.

In [`src/locale/index.js`](https://github.com/ElemeFE/element/blob/main/src/locale/index.js), the implementation is straightforward:

```javascript
export const use = function (l) {
  lang = l || lang;   // replace the current language table
};

```

When you call `locale.use`, the next invocation of `t` resolves keys against the new `lang` data.

### Example: Simple Language Switch with Built-in Packs

```javascript
// main.js
import Vue from 'vue';
import ElementUI, { locale } from 'element-ui';
import en from 'element-ui/src/locale/lang/en-US';
import zh from 'element-ui/src/locale/lang/zh-CN';

Vue.use(ElementUI, {
  locale: en   // default language
});

// Later, toggle language
function switchToChinese() {
  locale.use(zh);
}

```

*Source: [`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js) lines 84‑86* – `locale.use(opts.locale)`  

*Source: [`src/locale/index.js`](https://github.com/ElemeFE/element/blob/main/src/locale/index.js) lines 40‑42* – implementation of `use`.

## Using locale.i18n to Plug in a Custom Handler

The `locale.i18n` function allows you to override Element UI's internal translation logic with a custom handler, such as the one provided by **vue-i18n**.

In [`src/locale/index.js`](https://github.com/ElemeFE/element/blob/main/src/locale/index.js), the `t` function checks for a custom handler first:

```javascript
let i18nHandler = function () { … };

export const i18n = function (fn) {
  i18nHandler = fn || i18nHandler;   // replace the handler
};

export const t = function (path, options) {
  let value = i18nHandler.apply(this, arguments);
  if (value !== null && value !== undefined) return value; // custom handler wins
  // …fallback to built‑in table lookup
};

```

The default `i18nHandler` checks whether the current Vue instance (or the global `Vue`) has a `$t` method. If present, it forwards the call to that method, optionally merging Element's language pack into Vue's locale store on the first use.

### Example: Integrating with vue-i18n

```javascript
// i18n-setup.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import ElementUI, { locale } from 'element-ui';
import messages from './i18n/messages';   // { en: {...}, zh: {...} }

Vue.use(VueI18n);

const i18n = new VueI18n({
  locale: 'en',
  messages,
});

Vue.use(ElementUI, {
  // Pass Element's language pack (optional – Element will merge it later)
  locale: messages.en,
  // Forward Element's translation calls to vue‑i18n
  i18n: function (key, args) {
    // `this` is the Vue component instance
    return i18n.t(key, args);
  },
});

```

*Source: [`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js) lines 85‑86* – `locale.i18n(opts.i18n)`  

*Source: [`src/locale/index.js`](https://github.com/ElemeFE/element/blob/main/src/locale/index.js) lines 44‑46* – implementation of `i18n`.

## Component-Level Translation Usage

Components access translations through a mixin that injects the `t` method. In [`src/mixins/locale.js`](https://github.com/ElemeFE/element/blob/main/src/mixins/locale.js), the mixin delegates to the locale module:

```javascript
export default {
  methods: {
    t(...args) {
      return t.apply(this, args);
    }
  }
};

```

### Example: Using t Inside a Component

```vue
<template>
  <el-pagination
    :total="total"
    :page-size="pageSize"
    :current-page="currentPage"
    :layout="layout"
    :page-count="pageCount"
    :prev-text="prevText"
    :next-text="nextText">
  </el-pagination>
</template>

<script>
export default {
  name: 'MyTable',
  // Locale mixin adds the `t` method automatically
  mixins: [require('element-ui/src/mixins/locale').default],
  computed: {
    prevText() {
      return this.t('el.pagination.prev');
    },
    nextText() {
      return this.t('el.pagination.next');
    }
  }
};
</script>

```

*Source: [`src/mixins/locale.js`](https://github.com/ElemeFE/element/blob/main/src/mixins/locale.js) lines 4‑7* – the mixin forwards `t` calls.

## Adding Custom Language Packs

You can create and register custom language objects that follow the same structure as Element's built-in packs.

```javascript
// my-lang.js
export default {
  name: 'my',
  el: {
    pagination: {
      total: '共 {total} 条',
      prev: '上一页',
      next: '下一页'
    }
    // …other component translations
  }
};

// usage
import customLang from './my-lang';
import { locale } from 'element-ui';
locale.use(customLang);

```

## Key Files Reference

| File | Purpose | Link |
|------|---------|------|
| [`src/locale/index.js`](https://github.com/ElemeFE/element/blob/main/src/locale/index.js) | Core locale implementation (`use`, `t`, `i18n`) | [src/locale/index.js](https://github.com/ElemeFE/element/blob/dev/src/locale/index.js) |
| [`src/index.js`](https://github.com/ElemeFE/element/blob/main/src/index.js) | Global install hook that forwards `locale` and `i18n` options | [src/index.js](https://github.com/ElemeFE/element/blob/dev/src/index.js) |
| [`src/mixins/locale.js`](https://github.com/ElemeFE/element/blob/main/src/mixins/locale.js) | Vue mixin exposing `t` method to components | [src/mixins/locale.js](https://github.com/ElemeFE/element/blob/dev/src/mixins/locale.js) |
| `src/locale/lang/` | Built‑in language packs (e.g., `en-US`, `zh-CN`) | [src/locale/lang](https://github.com/ElemeFE/element/tree/dev/src/locale/lang) |

## Summary

- **`locale.use`** replaces the internal language table at runtime, allowing you to switch between Element UI's built-in language packs or custom objects.
- **`locale.i18n`** injects a custom translation handler that intercepts all `t` calls, enabling seamless integration with external libraries like **vue-i18n**.
- The **`t` method** is available globally through the locale module or locally via the `locale` mixin in components.
- Language packs are plain JavaScript objects following the `{ el: { component: { key: 'value' } } }` structure.

## Frequently Asked Questions

### What is the difference between locale.use and locale.i18n?

`locale.use` replaces the entire language dictionary that Element UI uses for its internal `t` function, effectively switching the language pack for all components. `locale.i18n`, on the other hand, registers a custom function that intercepts translation calls before Element's internal logic runs, allowing you to delegate translations to an external system like vue-i18n while keeping Element's language pack as a fallback.

### How do I change the language dynamically in a running Vue application?

Call `locale.use(newLang)` at any point after Element UI is installed. Because `locale.use` simply reassigns the internal `lang` variable in [`src/locale/index.js`](https://github.com/ElemeFE/element/blob/main/src/locale/index.js), all subsequent calls to `t` (including those triggered by component re-renders) will resolve against the new language object immediately. Ensure your components are reactive to the change by forcing an update or relying on computed properties that depend on the locale.

### Can I use Element UI's i18n system with vue-i18n without conflicts?

Yes. Pass a wrapper function to `locale.i18n` during Element UI installation that forwards calls to vue-i18n's `$t` method. Element's default `i18nHandler` already checks for the presence of `$t` on the Vue instance, but explicitly setting `locale.i18n` ensures consistent behavior. This allows vue-i18n to manage your application translations while Element UI continues to translate its internal component strings using the same mechanism.

### How do I add a completely custom language not included in Element UI?

Create a JavaScript module that exports an object matching Element's language pack structure: a `name` property and an `el` object containing nested keys for each component (e.g., `el.pagination.prev`). Import this module and pass it to `locale.use()`. The object will replace the internal language table, and components will immediately use your custom strings for all translated content.