---
type: how-to
title: Language
metaTitle: Language - JavaScript Data Grid | Handsontable
description: Set Handsontable's UI language to one of the built-in translations, or create your own language set using our templates.
permalink: /language
canonicalUrl: /language
tags:
  - internationalization
  - localization
  - translation
  - L10n
  - i18n
react:
  metaTitle: Language - React Data Grid | Handsontable
angular:
  metaTitle: Language - Angular Data Grid | Handsontable
vue:
  metaTitle: Language - Vue Data Grid | Handsontable
searchCategory: Guides
category: Internationalization
---
Set Handsontable's UI language to one of the built-in translations, or create your own language set using our templates.

[[toc]]

## Overview

You can easily change the text of the UI for the purpose of translating it to specific languages. We provide the developer with predefined languages, which can be applied by loading the language set and changing just one setting, and an ability to use their own language sets, created using templates of existing language files.

::: tip

To properly display RTL languages, configure Handsontable's [layout direction](@/guides/internationalization/layout-direction/layout-direction.md).

:::

## Load the prepared language files

To properly use the internationalization feature, you need to load the language sets. It's important that they're included after the Handsontable files. You can do it by getting the necessary files created with the UMD standard:

::: only-for javascript

<ol class="sl-steps">
<li>

**ES modules (ESM)**

```js
import Handsontable from 'handsontable/base';
import { registerLanguageDictionary, deDE } from 'handsontable/i18n';

registerLanguageDictionary(deDE);

const hot = new Handsontable(container, {
  language: deDE.languageCode,
});
```

</li>
<li>

**CommonJS (CJS)**

```js
const Handsontable = require('handsontable/base').default;
const { registerLanguageDictionary, deDE } = require('handsontable/i18n');

registerLanguageDictionary(deDE);

const hot = new Handsontable(container, {
  language: deDE.languageCode,
});
```

</li>
<li>

**Universal Module Definition (UMD)**

Languages included this way are ready to use immediately after loading the file. Each file contains a UMD loader that looks for `Handsontable` in a global/externals context. If `Handsontable` is available then it registers itself in the proper context.

```html
<script type="text/javascript" src="dist/handsontable.full.js"></script>
<script type="text/javascript" src="dist/languages/de-DE.js"></script>
<script>
  const hot = new Handsontable(container, {
    language: 'de-DE',
  });
</script>
```

</li>
</ol>

:::

::: only-for react

<ol class="sl-steps">
<li>

**ES modules (ESM)**

```js
import Handsontable from 'handsontable/base';
import { HotTable } from '@handsontable/react-wrapper';
import { registerLanguageDictionary, deDE } from 'handsontable/i18n';

registerLanguageDictionary(deDE);

const App = () => {
  return (
    <HotTable
      language={deDE.languageCode}
    />
  );
};
```

</li>
<li>

**CommonJS (CJS)**

```js
const Handsontable = require('handsontable/base').default;
const { registerLanguageDictionary, deDE } = require('handsontable/i18n');

registerLanguageDictionary(deDE);

const App = () => {
  return (
    <HotTable
      language={deDE.languageCode}
    />
});
```

</li>
</ol>

:::

::: only-for angular

<ol class="sl-steps">
<li>

**ES modules (ESM)**

```ts
import { Component } from "@angular/core";
import {
  GridSettings,
  HotTableComponent,
  HotTableModule,
} from "@handsontable/angular-wrapper";
import { registerLanguageDictionary, deDE } from "handsontable/i18n";

registerLanguageDictionary(deDE);

@Component({
  standalone: true,
  imports: [HotTableModule],
  template: ` <div>
    <hot-table [settings]="settings" />
  </div>`,
})
export class Component {
  settings: GridSettings = {
    language: deDE.languageCode,
  };
}
```

</li>
</ol>

:::

::: only-for vue

<ol class="sl-steps">
<li>

**ES modules (ESM)**

```js
import { ref } from 'vue';
import { HotTable } from '@handsontable/vue3';
import { registerAllModules } from 'handsontable/registry';
import { registerLanguageDictionary, deDE } from 'handsontable/i18n';

registerAllModules();
registerLanguageDictionary(deDE);

const hotSettings = ref({
  language: deDE.languageCode,
});
```

```html
<HotTable :settings="hotSettings" />
```

</li>
</ol>

:::

### Demo

To see the translated context menu, right-click on a cell.

Language files were loaded after loading Handsontable.

::: only-for javascript

::: example #example1 :hot-lang --js 1 --ts 2

@[code](@/content/guides/internationalization/language/javascript/example1.js)
@[code](@/content/guides/internationalization/language/javascript/example1.ts)

:::

:::

::: only-for react

::: example #example1 :react-languages --js 1 --ts 2

@[code](@/content/guides/internationalization/language/react/example1.jsx)
@[code](@/content/guides/internationalization/language/react/example1.tsx)

:::

:::

::: only-for angular

::: example #example1 :angular-languages --ts 1 --html 2

@[code](@/content/guides/internationalization/language/angular/example1.ts)
@[code](@/content/guides/internationalization/language/angular/example1.html)

:::

:::

::: only-for vue

::: example #example1 :vue3-languages

@[code](@/content/guides/internationalization/language/vue/example1.vue)

:::

:::

## List of translatable features

Below is a list of features which can be translated:

- Alignment
- Comments
- Context menu
- Cut and Copy (along with headers)
- Custom borders
- Dropdown menu
- Filtering
- Freezing
- Hiding columns
- Hiding rows
- Merge cells
- Nesting rows
- Pagination
- Read-only
- Undo and Redo
- Dialogs (including Loading indicator)

## List of available languages

::: tip

When using languages that require IME (Input Method Editor), such as Chinese, Japanese, or Korean, consider enabling the [`imeFastEdit`](@/api/options.md#imefastedit) option to improve editing experience. For more information, see the [IME support](@/guides/internationalization/ime-support/ime-support.md) guide.

:::

By default, Handsontable uses the **English - United States** language-country set (`en-US` code) for creating the text of UI elements. However, it can be used like every extra, "non-standard" language file, thus the `en-US.js` file can be found in `/dist/languages`, `/languages` and `/src/languages` folders. Currently, we also distribute extra language-country files:

<style>
.language-table td:nth-child(3) {
  white-space: nowrap;
}
</style>

<div class="language-table">

| Language file | Language | Code | Note |
| --- | --- | --- | --- |
| `ar-AR.js` | Arabic - Global | `ar-AR` | Set the [layout direction](@/guides/internationalization/language/language.md) to RTL |
| `cs-CZ.js` | Czech - Czechia | `cs-CZ` | |
| `de-CH.js` | German - Switzerland | `de-CH` | |
| `de-DE.js` | German - Germany | `de-DE` | |
| `es-MX.js` | Spanish - Mexico | `es-MX` | |
| `fa-IR.js` | Persian - Iran | `fa-IR` | |
| `fr-FR.js` | French - France | `fr-FR` | |
| `hr-HR.js` | Croatian - Croatia | `hr-HR` | |
| `it-IT.js` | Italian - Italy | `it-IT` | |
| `ja-JP.js` | Japanese - Japan | `ja-JP` | Enable [`imeFastEdit`](@/api/options.md#imefastedit) for better editing experience |
| `ko-KR.js` | Korean - Korea | `ko-KR` | Enable [`imeFastEdit`](@/api/options.md#imefastedit) for better editing experience |
| `lv-LV.js` | Latvian - Latvia | `lv-LV` | |
| `nb-NO.js` | Norwegian (Bokmål) - Norway | `nb-NO` | |
| `nl-NL.js` | Dutch - Netherlands | `nl-NL` | |
| `pl-PL.js` | Polish - Poland | `pl-PL` | |
| `pt-BR.js` | Portuguese - Brazil | `pt-BR` | |
| `ru-RU.js` | Russian - Russia | `ru-RU` | |
| `sr-SP.js` | Serbian (Latin) - Serbia | `sr-SP` | |
| `zh-CN.js` | Chinese - China | `zh-CN` | Enable [`imeFastEdit`](@/api/options.md#imefastedit) for better editing experience |
| `zh-TW.js` | Chinese - Taiwan | `zh-TW` | Enable [`imeFastEdit`](@/api/options.md#imefastedit) for better editing experience |

</div>

### Create custom languages

You can create custom language sets for your implementations, or share them, as they're easily applicable to any Handsontable implementation.

## Language file

It's really important for us, that the community is a important part of the growth of our library. We encourage you to create and share your translations!

Additional languages files should be placed in the `src/i18n/languages` folder of the Handsontable repository with name corresponding to the chosen language code (described below, for example: `es-VE.js`). You can incorporate your translations to the Handsontable library by sending us a [pull request](@/guides/tools-and-building/custom-builds/custom-builds.md). It's important, that your changes are not made to the `/languages` and `/dist/languages` directories! We will generate the final files to be placed there. After that, you'll be able to use the languages in Handsontable.

You can see a full template of a sample language at the bottom of this paragraph. We're basing it on our [default language pack](https://github.com/handsontable/handsontable/blob/master/handsontable/src/i18n/languages/en-US.js). Parts of the file creation process are described below.

<ol class="sl-steps">
<li>

**Add a file header comment**

The file should start with a comment containing the translation **authors** (separated by commas, for example: _Authors: Chris Wick, John Kyle_), **"last updated" date** (in format: _mmm dd, yyyy_, for example: _Last updated: Jan 01, 2017_) and a **description.**

```js
/**
* @preserve
* Authors: Chris Wick, John Kyle
* Last updated: Nov 15, 2017
*
* Description: Definition file for Spanish - Venezuela language-country.
*/
```

</li>
<li>

**Import the dictionary keys**

Import the dictionary keys to be used in the translation.

```js
import * as C from '../constants';
```

</li>
<li>

**Create the language dictionary object**

The language dictionary object should contain a `languageCode` key (in format: two lowercase letters, hyphen, two uppercase letters, for example: _languageCode: 'es-PY'_) which will determine the language code to be used in the language property in the `Handsontable` settings and dictionaries keys with their corresponding translations.

```js
const dictionary = {
  languageCode: 'es-VE',
  [C.CONTEXTMENU_ITEMS_ROW_ABOVE]: 'Insertar fila arriba',
  ...
}
```

</li>
<li>

**Export the dictionary**

Place a default export of the created dictionary.

```js
export default dictionary;
```

</li>
<li>

**Review the complete file**

A simple, sample language dictionary can look like the snippet below. The `/languages` and `/dist/languages` folders will be generated by the build process. Files from those localizations can be included as shown in [this section](#load-the-prepared-language-files). After loading them, you will be able to use the language. You can do it by changing the language setting of `Handsontable` to `es-VE`.

```js
/**
* @preserve
* Authors: Chris Wick, John Kyle
* Last updated: Nov 15, 2017
*
* Description: Definition file for Spanish - Venezuela language-country.
*/
import * as C from '../constants';

const dictionary = {
  languageCode: 'es-VE',
  [C.CONTEXTMENU_ITEMS_ROW_ABOVE]: 'Insertar fila arriba',
};

export default dictionary;
```

</li>
<li>

**Register the file in the index**

Import the already created file inside the `src/i18n/languages/index.js` file and export it like it's shown in the snippet below (keys in a alphabetical order).

```js {4,11}
import deCH from './de-CH';
import deDE from './de-DE';
import enUS from './en-US';
import esVE from './es-VE';
import plPL from './pl-PL';

export {
  deCH,
  deDE,
  enUS,
  esVE,
  plPL
};
```

</li>
<li>

**Share your translation**

You've created a language which can be used just by you or shared with others. We wait for at least 5 positive feedback from users to accept a created [pull request](@/guides/tools-and-building/custom-builds/custom-builds.md).

</li>
</ol>

### Local language

You can register a language dictionary which is not a part of the `Handsontable` package. To do so, use the static `Handsontable.languages.registerLanguageDictionary` method and the static constant `Handsontable.languages.dictionaryKeys` which are described briefly in the next section.

```js
const C = Handsontable.languages.dictionaryKeys;

Handsontable.languages.registerLanguageDictionary({
  languageCode: 'morse',
  // Your translation in the Morse code
  [C.FILTERS_BUTTONS_OK]: '--- -•-'
});
```

## Use custom keys in the translation

You can register a language dictionary containing custom keys. These entries can be used like any other keys, so you're not limited to using our pre-defined constants (the ones that are present within `src/i18n/constants.js` file and may be accessed by `Handsontable.languages.dictionaryKeys` alias).

```js
const enUSDictionary = Handsontable.languages.getLanguageDictionary('en-US');

enUSDictionary.customKey = 'Hello world';

Handsontable.languages.registerLanguageDictionary(enUSDictionary); // re-registration
Handsontable.languages.getTranslatedPhrase('en-US', 'customKey'); // 'Hello world'
```

## Static Handsontable methods and properties

Handsontable has a few static methods and properties connected with languages. They are stored in the `languages` key of the global `Handsontable` variable. All of them are described below.

### Get language dictionary for specific language code

Handsontable.languages.getLanguageDictionary(languageCode: `String`)

Returns: `Object`

### Get the registered language dictionaries

Handsontable.languages.getLanguagesDictionaries()

Returns: `Array`

### Get the phrase for specified dictionary key

Handsontable.languages.getTranslatedPhrase(languageCode: `String`, dictionaryKey: `String`, extraArguments: `Mixed`)

Returns: `Object`

### Register a language dictionary for a specific language code

Handsontable.languages.registerLanguageDictionary(languageCodeOrDictionary: `Mixed`, dictionary: `Object`)

Returns: `Object`

### Dictionary constants

Handsontable.languages.dictionaryKeys

Contains: `Object`

## Related articles

**Related guides**

<div class="boxes-list">

- [Layout direction](@/guides/internationalization/layout-direction/layout-direction.md)
- [Locale](@/guides/internationalization/locale/locale.md)
- [IME support](@/guides/internationalization/ime-support/ime-support.md)

</div>

**Configuration options**

<div class="boxes-list">

- [language](@/api/options.md#language)
- [layoutDirection](@/api/options.md#layoutdirection)
- [locale](@/api/options.md#locale)

</div>

**Core methods**

<div class="boxes-list">

- [getDirectionFactor()](@/api/core.md#getdirectionfactor)
- [getTranslatedPhrase()](@/api/core.md#gettranslatedphrase)
- [isLtr()](@/api/core.md#isltr)
- [isRtl()](@/api/core.md#isrtl)

</div>

**Hooks**

<div class="boxes-list">

- [afterLanguageChange](@/api/hooks.md#afterlanguagechange)
- [beforeLanguageChange](@/api/hooks.md#beforelanguagechange)

</div>
