Multi-language support system with built-in translations, custom language dictionary registration, and locale-aware formatting.
Core system for registering and managing language dictionaries.
/**
* Register a new language dictionary
* @param languageCode - ISO language code (e.g., 'en-US', 'fr-FR')
* @param dictionary - Language dictionary object
*/
function registerLanguageDictionary(languageCode: string, dictionary: LanguageDictionary): void;
/**
* Get registered language dictionary
* @param languageCode - ISO language code
* @returns Language dictionary or null if not found
*/
function getLanguageDictionary(languageCode: string): LanguageDictionary | null;
/**
* Check if language dictionary exists
* @param languageCode - ISO language code
* @returns True if dictionary is registered
*/
function hasLanguageDictionary(languageCode: string): boolean;
/**
* Get all registered language dictionaries
* @returns Object with language codes as keys
*/
function getLanguagesDictionaries(): { [languageCode: string]: LanguageDictionary };
/**
* Get valid/normalized language code
* @param languageCode - Input language code
* @returns Normalized language code
*/
function getValidLanguageCode(languageCode: string): string;
interface LanguageDictionary {
languageCode: string;
[key: string]: string | ((...args: any[]) => string);
}Functions for retrieving translated text with parameter substitution.
/**
* Get translated phrase for specific language
* @param languageCode - ISO language code
* @param dictionaryKey - Translation key
* @param argumentsArray - Arguments for phrase formatting
* @returns Translated and formatted text
*/
function getTranslatedPhrase(
languageCode: string,
dictionaryKey: string,
argumentsArray?: any[]
): string;
/**
* Translation key constants
*/
const DICTIONARY_KEYS = {
// Context menu items
CONTEXTMENU_ITEMS_ROW_ABOVE: 'Insert row above',
CONTEXTMENU_ITEMS_ROW_BELOW: 'Insert row below',
CONTEXTMENU_ITEMS_INSERT_LEFT: 'Insert column left',
CONTEXTMENU_ITEMS_INSERT_RIGHT: 'Insert column right',
CONTEXTMENU_ITEMS_REMOVE_ROW: 'Delete row',
CONTEXTMENU_ITEMS_REMOVE_COLUMN: 'Delete column',
CONTEXTMENU_ITEMS_UNDO: 'Undo',
CONTEXTMENU_ITEMS_REDO: 'Redo',
CONTEXTMENU_ITEMS_READ_ONLY: 'Read only',
CONTEXTMENU_ITEMS_CLEAR_COLUMN: 'Clear column',
// Filters
FILTERS_CONDITIONS_NONE: 'None',
FILTERS_CONDITIONS_EMPTY: 'Is empty',
FILTERS_CONDITIONS_NOT_EMPTY: 'Is not empty',
FILTERS_CONDITIONS_EQUAL: 'Is equal to',
FILTERS_CONDITIONS_NOT_EQUAL: 'Is not equal to',
FILTERS_CONDITIONS_BEGINS_WITH: 'Begins with',
FILTERS_CONDITIONS_ENDS_WITH: 'Ends with',
FILTERS_CONDITIONS_CONTAINS: 'Contains',
FILTERS_CONDITIONS_NOT_CONTAINS: 'Does not contain',
FILTERS_CONDITIONS_GREATER_THAN: 'Greater than',
FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL: 'Greater than or equal to',
FILTERS_CONDITIONS_LESS_THAN: 'Less than',
FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL: 'Less than or equal to',
FILTERS_CONDITIONS_BETWEEN: 'Is between',
FILTERS_CONDITIONS_NOT_BETWEEN: 'Is not between',
FILTERS_CONDITIONS_AFTER: 'After',
FILTERS_CONDITIONS_BEFORE: 'Before',
FILTERS_CONDITIONS_TODAY: 'Today',
FILTERS_CONDITIONS_TOMORROW: 'Tomorrow',
FILTERS_CONDITIONS_YESTERDAY: 'Yesterday',
// Buttons and labels
FILTERS_BUTTONS_OK: 'OK',
FILTERS_BUTTONS_CANCEL: 'Cancel',
FILTERS_BUTTONS_SELECT_ALL: 'Select all',
FILTERS_BUTTONS_CLEAR: 'Clear',
// Comments
CONTEXTMENU_ITEMS_ADD_COMMENT: 'Add comment',
CONTEXTMENU_ITEMS_EDIT_COMMENT: 'Edit comment',
CONTEXTMENU_ITEMS_REMOVE_COMMENT: 'Delete comment',
CONTEXTMENU_ITEMS_READ_ONLY_COMMENT: 'Read-only comment',
// Merge cells
CONTEXTMENU_ITEMS_MERGE_CELLS: 'Merge cells',
CONTEXTMENU_ITEMS_UNMERGE_CELLS: 'Unmerge cells',
// Column operations
CONTEXTMENU_ITEMS_HIDE_COLUMN: 'Hide column',
CONTEXTMENU_ITEMS_SHOW_COLUMN: 'Show column',
CONTEXTMENU_ITEMS_FREEZE_COLUMN: 'Freeze this column',
CONTEXTMENU_ITEMS_UNFREEZE_COLUMN: 'Unfreeze this column',
// Validation
VALIDATOR_MESSAGES_REQUIRED: 'This field is required',
VALIDATOR_MESSAGES_INVALID_DATE: 'Invalid date',
VALIDATOR_MESSAGES_INVALID_TIME: 'Invalid time',
VALIDATOR_MESSAGES_INVALID_NUMBER: 'Invalid number'
};Pre-built language dictionaries for common locales.
// Available built-in languages
const AVAILABLE_LANGUAGES = [
'en-US', // English (United States) - Default
'ar-AR', // Arabic
'ca-ES', // Catalan
'cs-CZ', // Czech
'da-DK', // Danish
'de-DE', // German
'es-MX', // Spanish (Mexico)
'fi-FI', // Finnish
'fr-FR', // French
'hu-HU', // Hungarian
'it-IT', // Italian
'ja-JP', // Japanese
'ko-KR', // Korean
'lv-LV', // Latvian
'nb-NO', // Norwegian Bokmål
'nl-NL', // Dutch
'pl-PL', // Polish
'pt-BR', // Portuguese (Brazil)
'ru-RU', // Russian
'sk-SK', // Slovak
'sv-SE', // Swedish
'tr-TR', // Turkish
'zh-CN', // Chinese (Simplified)
'zh-TW' // Chinese (Traditional)
];
// Import specific language
import { registerLanguageDictionary, deDE } from 'handsontable/i18n';
registerLanguageDictionary(deDE);
// Or import all languages at once
import 'handsontable/languages/all';Configure language settings for the entire grid instance.
// Language configuration in grid settings
interface GridLanguageSettings {
language?: string; // ISO language code
locale?: string; // Locale for number/date formatting
layoutDirection?: 'ltr' | 'rtl'; // Text direction
}
// Usage in grid initialization
const hot = new Handsontable(container, {
data: myData,
language: 'de-DE',
locale: 'de-DE',
layoutDirection: 'ltr'
});
// Change language at runtime
hot.updateSettings({
language: 'fr-FR'
});Create and register custom language dictionaries for specific needs.
/**
* Custom language dictionary structure
*/
interface CustomLanguageDictionary extends LanguageDictionary {
languageCode: string;
// Context menu translations
CONTEXTMENU_ITEMS_ROW_ABOVE?: string;
CONTEXTMENU_ITEMS_ROW_BELOW?: string;
CONTEXTMENU_ITEMS_REMOVE_ROW?: string;
CONTEXTMENU_ITEMS_REMOVE_COLUMN?: string;
CONTEXTMENU_ITEMS_UNDO?: string;
CONTEXTMENU_ITEMS_REDO?: string;
// Filter translations
FILTERS_CONDITIONS_EQUAL?: string;
FILTERS_CONDITIONS_CONTAINS?: string;
FILTERS_CONDITIONS_GREATER_THAN?: string;
FILTERS_BUTTONS_OK?: string;
FILTERS_BUTTONS_CANCEL?: string;
// Comments
CONTEXTMENU_ITEMS_ADD_COMMENT?: string;
CONTEXTMENU_ITEMS_EDIT_COMMENT?: string;
CONTEXTMENU_ITEMS_REMOVE_COMMENT?: string;
// Custom phrases with parameters
CUSTOM_MESSAGE?: (...args: any[]) => string;
[key: string]: string | ((...args: any[]) => string);
}Formatting options that respect locale settings for numbers, dates, and text.
// Numeric formatting with locale
interface LocaleNumericFormat {
pattern?: string; // Number pattern
culture?: string; // Locale code
currency?: string; // Currency code (ISO 4217)
currencySymbol?: string; // Currency symbol
thousandSeparator?: string; // Thousands separator
decimalSeparator?: string; // Decimal separator
}
// Date formatting with locale
interface LocaleDateFormat {
dateFormat?: string; // Date format pattern
locale?: string; // Locale for formatting
timezone?: string; // Timezone identifier
}
// Column configuration with locale formatting
{
type: 'numeric',
numericFormat: {
pattern: '0,0.00 $',
culture: 'en-US',
currency: 'USD'
}
}
{
type: 'date',
dateFormat: 'DD/MM/YYYY',
locale: 'en-GB'
}Built-in support for right-to-left languages and layouts.
// RTL configuration
interface RTLSettings {
layoutDirection: 'rtl';
language: string; // RTL language code like 'ar-AR', 'he-IL'
}
// Enable RTL layout
const hot = new Handsontable(container, {
data: myData,
language: 'ar-AR',
layoutDirection: 'rtl',
// RTL affects:
// - Text alignment in cells
// - Column order (rightmost is first)
// - Scroll direction
// - Context menu positioning
// - Selection handles
});Usage Examples:
// Register custom language
import { registerLanguageDictionary } from 'handsontable/i18n';
const customSpanish = {
languageCode: 'es-CUSTOM',
CONTEXTMENU_ITEMS_ROW_ABOVE: 'Insertar fila arriba',
CONTEXTMENU_ITEMS_ROW_BELOW: 'Insertar fila abajo',
CONTEXTMENU_ITEMS_REMOVE_ROW: 'Eliminar fila',
FILTERS_CONDITIONS_EQUAL: 'Es igual a',
FILTERS_CONDITIONS_CONTAINS: 'Contiene',
FILTERS_BUTTONS_OK: 'Aceptar',
FILTERS_BUTTONS_CANCEL: 'Cancelar',
// Custom message with parameters
CUSTOM_ROWS_SELECTED: (count) => `${count} filas seleccionadas`
};
registerLanguageDictionary(customSpanish);
// Use in grid
const hot = new Handsontable(container, {
data: myData,
language: 'es-CUSTOM',
contextMenu: true,
filters: true
});
// Get translated phrase programmatically
import { getTranslatedPhrase } from 'handsontable/i18n';
const message = getTranslatedPhrase('es-CUSTOM', 'CUSTOM_ROWS_SELECTED', [5]);
console.log(message); // "5 filas seleccionadas"
// Multi-language application
const supportedLanguages = ['en-US', 'de-DE', 'fr-FR', 'es-MX'];
const userLanguage = navigator.language || 'en-US';
const gridLanguage = supportedLanguages.includes(userLanguage) ? userLanguage : 'en-US';
hot.updateSettings({
language: gridLanguage
});
// Dynamic language switching
function switchLanguage(langCode) {
hot.updateSettings({
language: langCode
});
// Update any custom UI elements
document.querySelector('#save-button').textContent =
getTranslatedPhrase(langCode, 'BUTTON_SAVE');
}