# Internationalization

- Human documentation: [https://docs.univer.ai/guides/sheets/getting-started/i18n](https://docs.univer.ai/guides/sheets/getting-started/i18n)

- Agent Markdown: [https://docs.univer.ai/guides/sheets/getting-started/i18n.md](https://docs.univer.ai/guides/sheets/getting-started/i18n.md)

- Requested language: `en-US`

- Content language: `en-US`

- Documentation version: `1.0.2`

- Source: [sheets/getting-started/i18n.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/getting-started/i18n.mdx)

---

## Interface language

`locale` selects the language pack for menus, tooltips, dialogs, and other translated UI. `locales` registers these packs without selecting a language. This setting is shared by the units in the Univer instance. Use `LocaleType` values, such as `LocaleType.EN_US`.

* **All products: UI**: `locale` changes translated menus, tooltips, dialogs, and plugin labels. It does not translate user content or rename existing units.
* **Sheets: cell formats and formulas**: Cell number/date rendering uses the number-format locale override, then the workbook snapshot `locale`, then the instance `locale`. `region` does not replace these settings. Formula behavior such as `DOLLAR` and financial-result currency formats still uses `locale`; CJK input normalization also uses `locale`.
* **Docs: statistics**: `locale` is used for word segmentation/counting.

### Changing language at runtime

Load all language packs for the installed plugins or presets before switching language. `loadLocales()` merges translations without switching; `setLocale()` selects them without downloading anything. Missing translation keys are displayed as keys. This example loads the shared UI pack; merge the target-language packs for your other installed plugins in the same call.

```typescript
import { LocaleType, mergeLocales } from '@univerjs/core'
import UIEnUS from '@univerjs/ui/locale/en-US'

univerAPI.loadLocales(LocaleType.EN_US, mergeLocales(UIEnUS))
univerAPI.setLocale(LocaleType.EN_US)

console.log(univerAPI.getCurrentLocale()) // enUS
```

### Registering Language Packs in Plugin Mode

To register language packs in plugin mode, you need to import the corresponding language packs from the plugins that provide them and merge them into a single object to pass to the `Univer` instance. Here is an example:

```typescript
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'
import DesignEnUS from '@univerjs/design/locale/en-US' // [!code highlight]
import SheetsUIEnUS from '@univerjs/sheets-ui/locale/en-US' // [!code highlight]
import UIEnUS from '@univerjs/ui/locale/en-US' // [!code highlight]

const univer = new Univer({
  locale: LocaleType.EN_US,
  locales: {
    [LocaleType.EN_US]: mergeLocales(
      DesignEnUS, // [!code highlight]
      UIEnUS, // [!code highlight]
      SheetsUIEnUS, // [!code highlight]
    ),
  },
})
```

> [!WARNING: Caution]
> Not all plugins include language packs. We will specify this in the documentation for each feature.

### Registering Language Packs in Preset Mode

Preset packages already include the corresponding plugin language packs, you just need to import them from the preset.

```typescript
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US' // [!code highlight]
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'

const { univerAPI } = createUniver({
  locale: LocaleType.EN_US,
  locales: {
    [LocaleType.EN_US]: mergeLocales(
      UniverPresetSheetsCoreEnUS, // [!code highlight]
    ),
  },
  presets: [
    UniverSheetsCorePreset(),
  ],
})
```

### Merging language packs

`mergeLocales` Method is used to merge multiple plugin or preset language packs into a complete language pack object. You can use it as follows:

#### Plugin Mode

```typescript
import { mergeLocales } from '@univerjs/core'

// You can pass multiple language pack objects to merge
const locales = mergeLocales(
  plugin1Locales,
  plugin2Locales,
  presetLocales,
)
// You can also pass an array of language pack objects
const locales = mergeLocales([
  plugin1Locales,
  plugin2Locales,
  presetLocales,
])
```

#### Preset Mode

```typescript
import { mergeLocales } from '@univerjs/presets'

// You can pass multiple language pack objects to merge
const locales = mergeLocales(
  plugin1Locales,
  plugin2Locales,
  presetLocales,
)
// You can also pass an array of language pack objects
const locales = mergeLocales([
  plugin1Locales,
  plugin2Locales,
  presetLocales,
])
```

### Custom Language Packs

Univer also supports custom language packs. You can assemble a language pack object as needed and pass it to the `Univer` instance. The preset language packs are generally stored in the `<rootDir>/packages/<PLUGIN_NAME>/locale` directory.

```typescript
import { LocaleType, Univer } from '@univerjs/core'

const univer = new Univer({
  locale: LocaleType.JA_JP,
  locales: {
    [LocaleType.JA_JP]: {
      ui: {
        shortcut: {
          undo: '元に戻す',
          redo: 'やり直す',
        },
      },
    },
  },
})
```

### Contributing Translations

Univer currently provides the following built-in language packs:

* `zh-CN`: Simplified Chinese
* `en-US`: English
* `zh-TW`: Traditional Chinese
* `zh-HK`: Traditional Chinese (Hong Kong)
* `ru-RU`: Russian
* `vi-VN`: Vietnamese
* `fa-IR`: Persian
* `fr-FR`: French
* `ja-JP`: Japanese
* `ko-KR`: Korean
* `es-ES`: Spanish
* `ca-ES`: Catalan
* `sk-SK`: Slovakian
* `ar-SA`: Arabic
* `de-DE`: German
* `id-ID`: Indonesian
* `it-IT`: Italian
* `pl-PL`: Polish
* `pt-BR`: Portuguese (Brazilian)

Univer is an open source project full of inclusiveness, and we welcome developers from all over the world to add or improve locales for Univer.

## Regional settings

`region` selects the regional conventions used by regional features. This setting is shared by the units in the Univer instance.

Use `LocaleType` values for both settings: for example, `LocaleType.EN_US` is `enUS`, while `en-US` is the language-pack file name / BCP 47 tag. Do not pass country codes such as `US` or `SG` as `region`. A region does not require its language pack when the UI uses a different locale.

Without an explicit `region`, it follows `locale`, including later `setLocale()` calls. Setting `region` at initialization or calling `setRegion()` stops that automatic following. Subsequent language changes keep the explicitly selected region. There is no public reset-to-follow API; update both values yourself when they should change together.

Add `region: LocaleType.DE_DE` next to `locale` in either `createUniver()` or `new Univer()` to keep your UI language while using German regional conventions.

```typescript
import { LocaleType } from '@univerjs/core'

univerAPI.setRegion(LocaleType.DE_DE)
univerAPI.setLocale(LocaleType.EN_US)

console.log(univerAPI.getCurrentRegion()) // deDE
```

Here the UI switches to English and regional formatting stays German. `getCurrentLocale()` and `getCurrentRegion()` return the effective identifiers. To change both together, call both setters with the same `LocaleType` value.

* **Sheets: currency controls**: `region` controls the currency toolbar icon, currency/accounting choices and previews, and the pattern applied by the currency command. Changing it does not rewrite existing cell formats or convert monetary values.
* **Docs: statistics**: `region` formats the displayed counts in the statistics dialog and status bar (for example, grouping separators); changing `region` does not change the counting rules.
* **Thread comments, when enabled**: `region` controls the displayed date/time format, with 24-hour time and Latin digits. `locale` controls comment UI text. Neither changes stored timestamps; `region` is not a timezone setting.
* **Boards, Slides, Bases, PDFs**: `locale` controls translated UI. `region` is available for shared features that consume it, such as thread comments when integrated; it does not automatically reformat board/slide text, Base fields, or PDF content.

## Right-to-left layout

> [!WARNING: Caution]
> RTL currently supports only the UI layer. The rendering layer does not support RTL.

Layout direction is separate: use `direction` at initialization or `univerAPI.setDirection('rtl')` / `setDirection('ltr')`. Changing `locale` or `region` alone does not switch the layout direction.

```typescript
univerAPI.setDirection('rtl')
```
