The TablixJS localization system provides comprehensive internationalization (i18n) support, allowing you to create multilingual data tables with ease. The system is built into the core library and provides seamless translation of all user-facing strings.
Intl APIsOut of the box, TablixJS includes:
Additional languages can be added by providing translation objects. Common languages are automatically loaded when needed.
// Create a table with default English
const table = new Tablix('#myTable', {
data: myData,
columns: myColumns
});
// Access translations
console.log(table.t('pagination.next')); // "Next"
import { frenchTranslations } from './src/locales/fr.js';
const table = new Tablix('#myTable', {
data: myData,
columns: myColumns,
language: 'fr',
translations: {
fr: frenchTranslations
}
});
console.log(table.t('pagination.next')); // "Suivant"
// Start with English
const table = new Tablix('#myTable', {
data: myData,
columns: myColumns,
language: 'en'
});
// Switch to French (auto-loads if not present)
table.setLanguage('fr');
// Table automatically re-renders with French text, including filter dropdowns
// Switch to Serbian (auto-loads translations)
table.setLanguage('sr');
// Add custom translations and switch
table.addTranslations('de', germanTranslations);
table.setLanguage('de');
TablixJS automatically loads common language packs when you switch to them:
// These languages are automatically loaded when requested
table.setLanguage('fr'); // Auto-loads French translations
table.setLanguage('es'); // Auto-loads Spanish translations
table.setLanguage('sr'); // Auto-loads Serbian translations
// For other languages, add translations first
table.addTranslations('de', germanTranslations);
table.setLanguage('de');
t(key, params = {})Get a localized string by translation key.
Parameters:
key (string): Translation key (e.g., 'pagination.next')params (object): Optional parameters for substitutionReturns: Localized string
Example:
table.t('pagination.showingRecords', {
startRow: 1,
endRow: 10,
totalRows: 100
}); // "Showing 1-10 of 100 records"
setLanguage(language)Set the current language and re-render the table.
Parameters:
language (string): Language code (e.g., 'fr', 'es')Example:
table.setLanguage('fr');
addLanguagePack(language, translations, setAsCurrent = false)Add a complete language pack with convenience options.
Parameters:
language (string): Language codetranslations (object): Complete translation key-value pairssetAsCurrent (boolean): Whether to immediately set this as the current languageExample:
// Add German and immediately switch to it
table.addLanguagePack('de', germanTranslations, true);
// Or add without switching
table.addLanguagePack('it', italianTranslations);
table.setLanguage('it'); // Switch later
addTranslations(language, translations)Add translations for a specific language.
Parameters:
language (string): Language codetranslations (object): Translation key-value pairsExample:
table.addTranslations('de', {
'pagination.next': 'Nächste',
'pagination.previous': 'Vorherige'
});
getCurrentLanguage()Get the current language code.
Returns: Current language string
getAvailableLanguages()Get array of available language codes.
Returns: Array of language strings
hasLanguage(language)Check if a language is available.
Parameters:
language (string): Language code to checkReturns: Boolean
formatNumber(number, options = {})Format a number using the current locale.
Parameters:
number (number): Number to formatoptions (object): Intl.NumberFormat optionsExample:
table.formatNumber(1234.56, { style: 'currency', currency: 'EUR' });
// "€1,234.56" in English, "1 234,56 €" in French
formatDate(date, options = {})Format a date using the current locale.
Parameters:
date (Date|string|number): Date to formatoptions (object): Intl.DateTimeFormat optionsExample:
table.formatDate(new Date(), { dateStyle: 'medium' });
// "Jan 15, 2024" in English, "15 janv. 2024" in French
TablixJS comes with complete language packs for:
import { englishTranslations } from './src/locales/en.js';
import { frenchTranslations } from './src/locales/fr.js';
import { spanishTranslations } from './src/locales/es.js';
import { serbianTranslations } from './src/locales/sr.js';
TablixJS automatically loads these language packs when you call setLanguage():
No need to manually import or add these translations - just use table.setLanguage('fr') and they'll be loaded automatically.
All translation keys follow a hierarchical structure:
{
// General terms
'general.loading': 'Loading...',
'general.error': 'Error',
'general.noData': 'No data available',
// Search functionality
'search.placeholder': 'Search...',
'search.clear': 'Clear search',
// Pagination
'pagination.first': 'First',
'pagination.previous': 'Previous',
'pagination.next': 'Next',
'pagination.last': 'Last',
'pagination.showingRecords': 'Showing {startRow}-{endRow} of {totalRows} records',
// Sorting
'sort.sortAscending': 'Sort ascending',
'sort.sortDescending': 'Sort descending',
'sort.sortedAscending': 'Sorted ascending',
'sort.sortedDescending': 'Sorted descending',
'sort.notSorted': 'Not sorted',
// Selection
'selection.selectRow': 'Select row',
'selection.selectAll': 'Select all',
'selection.selectedCount': '{count} selected',
// Filtering
'filter.filter': 'Filter',
'filter.clearFilter': 'Clear filter',
'filter.filterColumn': 'Filter column',
'filter.filterByValue': 'Filter by Value',
'filter.filterByCondition': 'Filter by Condition',
'filter.searchValues': 'Search values...',
'filter.selectAll': 'Select All',
'filter.noValuesAvailable': 'No values available',
'filter.addCondition': 'Add Condition',
'filter.removeCondition': 'Remove condition',
'filter.value': 'Value',
'filter.apply': 'Apply',
'filter.clear': 'Clear',
'filter.cancel': 'Cancel',
'filter.contains': 'Contains',
'filter.equals': 'Equals',
// Controls
'controls.refresh': 'Refresh data',
'controls.export': 'Export data',
// Error messages
'error.loadingData': 'Failed to load data',
'error.networkError': 'Network error occurred',
// Accessibility
'accessibility.table': 'Data table',
'accessibility.sortableColumn': 'Sortable column'
}
const germanTranslations = {
'general.loading': 'Laden...',
'general.error': 'Fehler',
'general.noData': 'Keine Daten verfügbar',
'search.placeholder': 'Suchen...',
'pagination.next': 'Nächste',
'pagination.previous': 'Vorherige',
'pagination.showingRecords': 'Zeige {startRow}-{endRow} von {totalRows} Datensätzen',
'filter.filter': 'Filter',
'filter.apply': 'Anwenden',
'filter.clear': 'Löschen',
'filter.cancel': 'Abbrechen',
// ... add more translations as needed
};
// Add and immediately switch to German
table.addLanguagePack('de', germanTranslations, true);
table.addTranslations('de', germanTranslations);
table.setLanguage('de');
// Just switch - translations auto-load if available
table.setLanguage('fr'); // French auto-loads
table.setLanguage('es'); // Spanish auto-loads
table.setLanguage('sr'); // Serbian auto-loads
You can override or extend translations for your specific use case:
const customerTranslations = {
'general.noData': 'No customers found',
'search.placeholder': 'Search customers...',
'pagination.showingRecords': 'Displaying {startRow}-{endRow} of {totalRows} customers'
};
const table = new Tablix('#myTable', {
data: customerData,
columns: customerColumns,
language: 'en-custom',
translations: {
'en-custom': customerTranslations
}
});
Translations support parameter substitution using {paramName} syntax:
// Translation with parameters
'welcome.message': 'Welcome back, {username}! You have {count} new messages.'
// Usage
table.t('welcome.message', {
username: 'John',
count: 5
}); // "Welcome back, John! You have 5 new messages."
Plugin developers can easily add their own translations:
class ExportPlugin {
constructor(table) {
this.table = table;
this.addTranslations();
}
addTranslations() {
// Add English translations
this.table.addTranslations('en', {
'export.csv': 'Export as CSV',
'export.excel': 'Export as Excel',
'export.success': 'Export completed successfully'
});
// Add French translations
this.table.addTranslations('fr', {
'export.csv': 'Exporter en CSV',
'export.excel': 'Exporter en Excel',
'export.success': 'Export terminé avec succès'
});
}
createExportButton() {
const button = document.createElement('button');
button.textContent = this.table.t('export.csv');
return button;
}
}
pluginName.keyName// Good plugin translation structure
{
'myPlugin.title': 'My Plugin',
'myPlugin.button.save': 'Save Data',
'myPlugin.message.success': 'Operation completed successfully',
'myPlugin.error.validation': 'Please check your input'
}
TablixJS automatically updates all UI components when the language changes, including:
// When switching languages, everything updates automatically
table.setLanguage('fr');
// Filter dropdown now shows "Filtrer", "Appliquer", "Effacer", etc.
table.setLanguage('sr');
// Filter dropdown now shows "Filter", "Primeni", "Obriši", etc.
TablixJS can intelligently handle language switching with graceful fallbacks:
// Try to load a language - auto-loads if available, falls back gracefully
function switchToUserLanguage(userLang) {
if (table.hasLanguage(userLang)) {
table.setLanguage(userLang);
} else {
// Try auto-loading common languages
table.setLanguage(userLang); // Will auto-load fr/es/sr if requested
// Check if it loaded successfully
if (!table.hasLanguage(userLang)) {
console.warn(`Language ${userLang} not available, staying with current language`);
}
}
}
class StatusRenderer {
static getStatusText(table, status) {
const statusKeys = {
active: 'status.active',
inactive: 'status.inactive',
pending: 'status.pending'
};
return table.t(statusKeys[status] || 'status.unknown');
}
}
class TimeBasedGreeting {
static getGreeting(table) {
const hour = new Date().getHours();
if (hour < 12) return table.t('greeting.morning');
if (hour < 18) return table.t('greeting.afternoon');
return table.t('greeting.evening');
}
}
const richTranslations = {
'help.tip': 'Use <kbd>Ctrl+F</kbd> to search or <strong>click</strong> the search box',
'error.withLink': 'Error occurred. <a href="/contact">Contact support</a>.'
};
function getSelectionText(table, count) {
if (count === 0) return table.t('selection.none');
if (count === 1) return table.t('selection.single');
return table.t('selection.multiple', { count });
}
// Good
'message.itemsSelected': '{count} item(s) selected'
// Avoid
'message.itemsSelected': ' item(s) selected' // Requires concatenation
The localization system supports accessibility by providing proper ARIA labels and screen reader friendly text:
// Accessible sort indicators
'sort.sortedAscending': 'Sorted ascending',
'accessibility.sortableColumn': 'Sortable column',
'accessibility.table': 'Data table'
import React, { useState, useEffect } from 'react';
import Tablix from 'tablixjs';
function DataTable({ language = 'en' }) {
const [table, setTable] = useState(null);
useEffect(() => {
const tableInstance = new Tablix('#table', {
data: myData,
columns: myColumns,
language: language
});
setTable(tableInstance);
return () => tableInstance.destroy();
}, []);
useEffect(() => {
if (table) {
// Auto-loads translations for fr/es/sr, updates all components
table.setLanguage(language);
}
}, [table, language]);
const handleLanguageChange = (newLang) => {
// Filter dropdowns and all UI automatically update
table.setLanguage(newLang);
};
return (
<div>
<select onChange={(e) => handleLanguageChange(e.target.value)}>
<option value="en">English</option>
<option value="fr">Français</option>
<option value="es">Español</option>
<option value="sr">Српски</option>
</select>
<div id="table" />
</div>
);
}
<template>
<div>
<select v-model="currentLanguage" @change="updateLanguage">
<option value="en">English</option>
<option value="fr">Français</option>
<option value="es">Español</option>
<option value="sr">Српски</option>
</select>
<div ref="tableContainer"></div>
</div>
</template>
<script>
import Tablix from 'tablixjs';
export default {
data() {
return {
currentLanguage: 'en',
table: null
};
},
mounted() {
this.table = new Tablix(this.$refs.tableContainer, {
data: this.myData,
columns: this.myColumns,
language: this.currentLanguage
});
},
methods: {
updateLanguage() {
if (this.table) {
// Automatically handles filter dropdown translations
this.table.setLanguage(this.currentLanguage);
}
}
},
watch: {
currentLanguage: 'updateLanguage'
},
beforeUnmount() {
if (this.table) {
this.table.destroy();
}
}
};
</script>
Translation not showing:
table.getCurrentLanguage()table.setLanguage() - they auto-loadtable.addLanguagePack() Filter dropdowns still in English:
table.setLanguage() not just setting a config optionAuto-loading not working:
addTranslations() or addLanguagePack()Fallback not working:
Plugin translations not appearing:
addLanguagePack() method for easier plugin translation managementEnable translation debugging and test the new features:
// Check available languages (should include auto-loaded ones)
console.log(table.getAvailableLanguages()); // ['en', 'fr', 'es', 'sr']
// Check current language
console.log(table.getCurrentLanguage());
// Test auto-loading
table.setLanguage('sr'); // Should auto-load Serbian
console.log(table.hasLanguage('sr')); // Should be true
// Test translation with filter keys
console.log(table.t('filter.apply')); // Should show localized "Apply" button text
console.log(table.t('filter.filterByValue')); // Should show "Filter by Value"
// Test the new convenience method
table.addLanguagePack('de', germanTranslations);
console.log(table.hasLanguage('de')); // Should be true
// Check if language exists
console.log(table.hasLanguage('fr')); // Should be true (auto-loaded)
addTranslations() callssetLanguage() callsThis comprehensive localization system makes TablixJS truly international, providing seamless multilingual support while maintaining excellent developer experience and performance.