Core utilities and components for Apache Superset's frontend UI framework providing data visualization, formatting, and chart composition capabilities
—
This module provides comprehensive internationalization (i18n) support for Superset applications, enabling multi-language user interfaces with proper pluralization, locale-specific formatting, and dynamic translation loading. The translation system is built on the Jed library and provides both singleton and instance-based APIs.
The translation module uses a singleton pattern to manage a global translation instance while supporting custom translator configurations for specific use cases. It supports 10+ languages including English, Spanish, French, German, Italian, Japanese, Korean, Portuguese, Russian, and Chinese.
Primary functions for translating text in your application:
import { t, tn } from '@superset-ui/core';
// Basic translation
function t(text: string, ...args: unknown[]): string;
// Pluralized translation with count
function tn(
singular: string,
plural: string,
count: number,
...args: unknown[]
): string;Functions for configuring the global translator instance:
import {
configure,
addTranslation,
addTranslations,
addLocaleData,
resetTranslation
} from '@superset-ui/core';
// Configure global translator
function configure(config?: TranslatorConfig): Translator;
// Add individual translations
function addTranslation(key: string, translations: string[]): Translator;
// Add multiple translations at once
function addTranslations(translations: Translations): Translator;
// Add locale-specific data
function addLocaleData(data: LocaleData): Translator;
// Reset translation system
function resetTranslation(): void;Type definitions for the translation system:
// Supported locales
type Locale =
| 'de' // German
| 'en' // English
| 'es' // Spanish
| 'fr' // French
| 'it' // Italian
| 'ja' // Japanese
| 'ko' // Korean
| 'pt' // Portuguese
| 'pt_BR' // Portuguese (Brazil)
| 'ru' // Russian
| 'zh'; // Chinese
// Translation configuration
interface TranslatorConfig {
languagePack?: LanguagePack;
}
// Language pack structure
interface LanguagePack extends JedOptions {
locale_data: {
superset: DomainData & {
'': {
domain: 'superset';
lang: Locale;
plural_forms: string;
};
};
};
}
// Translation mappings
type Translations = { [key: string]: string | string[] };
// Locale-specific data
type LocaleData = Partial<Record<Locale, Translations>>;Extended Jed instance with Superset-specific typing:
interface Jed extends BaseJed {
options: LanguagePack;
// Core Jed methods
gettext(key: string): string;
ngettext(singular: string, plural: string, count: number): string;
pgettext(context: string, key: string): string;
npgettext(context: string, singular: string, plural: string, count: number): string;
}
// Jed domain data structure
interface DomainData {
[msgid: string]: string | string[];
}
// Jed configuration options
interface JedOptions {
domain?: string;
locale_data?: { [domain: string]: DomainData };
debug?: boolean;
}Core translator class that manages translations for a specific locale:
import { Translator } from '@superset-ui/core';
class Translator {
readonly i18n: Jed;
readonly locale: Locale;
constructor(config?: TranslatorConfig);
// Translation methods
translate(text: string, ...args: unknown[]): string;
translateWithNumber(
singular: string,
plural: string,
count: number,
...args: unknown[]
): string;
// Dynamic translation management
addTranslation(key: string, texts: ReadonlyArray<string>): this;
addTranslations(translations: Translations): this;
addLocaleData(data: LocaleData): this;
// Locale management
getLocale(): Locale;
}import { t, tn, configure } from '@superset-ui/core';
// Configure with language pack
configure({
languagePack: {
domain: 'superset',
locale_data: {
superset: {
'': {
domain: 'superset',
lang: 'es',
plural_forms: 'nplurals=2; plural=(n != 1)'
},
'Hello World': ['Hola Mundo'],
'Save': ['Guardar'],
'Delete': ['Eliminar']
}
}
}
});
// Basic translation
const greeting = t('Hello World'); // "Hola Mundo"
const saveButton = t('Save'); // "Guardar"
// Pluralized translation
const itemCount = tn('item', 'items', 1); // "item"
const itemsCount = tn('item', 'items', 5); // "items"import {
addTranslation,
addTranslations,
addLocaleData
} from '@superset-ui/core';
// Add single translation
addTranslation('New Feature', ['Nueva Característica']);
// Add multiple translations
addTranslations({
'Dashboard': ['Panel de Control'],
'Charts': ['Gráficos'],
'Datasets': ['Conjuntos de Datos']
});
// Add locale-specific data
addLocaleData({
'es': {
'Welcome': 'Bienvenido',
'Goodbye': 'Adiós'
},
'fr': {
'Welcome': 'Bienvenue',
'Goodbye': 'Au revoir'
}
});import { Plugin, addTranslations } from '@superset-ui/core';
class ChartPlugin extends Plugin {
constructor(config: { translations?: Translations }) {
super();
this.configure(config);
}
register() {
// Add plugin-specific translations
if (this.config.translations) {
addTranslations(this.config.translations);
}
return super.register();
}
}
// Register plugin with translations
const myChartPlugin = new ChartPlugin({
translations: {
'My Chart': ['Mi Gráfico'],
'Configure Chart': ['Configurar Gráfico'],
'No data available': ['No hay datos disponibles']
}
});
myChartPlugin.register();import { Translator } from '@superset-ui/core';
// Create custom translator for specific module
const moduleTranslator = new Translator({
languagePack: {
domain: 'my-module',
locale_data: {
superset: {
'': {
domain: 'my-module',
lang: 'fr',
plural_forms: 'nplurals=2; plural=(n > 1)'
},
'Settings': ['Paramètres'],
'Options': ['Options']
}
}
}
});
// Use custom translator
const settingsLabel = moduleTranslator.translate('Settings'); // "Paramètres"import React from 'react';
import { t, tn } from '@superset-ui/core';
interface NotificationProps {
count: number;
type: string;
}
const NotificationComponent: React.FC<NotificationProps> = ({ count, type }) => {
return (
<div>
<h3>{t('Notifications')}</h3>
<p>
{tn(
`You have ${count} ${type} notification`,
`You have ${count} ${type} notifications`,
count
)}
</p>
</div>
);
};import { t } from '@superset-ui/core';
// Add translations with placeholders
addTranslations({
'Welcome back, {name}!': ['¡Bienvenido de nuevo, {name}!'],
'You have {count} new messages': ['Tienes {count} mensajes nuevos']
});
// Use with interpolation
const welcomeMessage = t('Welcome back, {name}!', { name: 'John' });
const messageCount = t('You have {count} new messages', { count: 5 });import { Translator } from '@superset-ui/core';
// Create specialized translators for different domains
const dashboardTranslator = new Translator({
languagePack: {
domain: 'dashboard',
locale_data: {
superset: {
'': { domain: 'dashboard', lang: 'de', plural_forms: 'nplurals=2; plural=(n != 1)' },
'Dashboard': ['Dashboard'],
'Edit': ['Bearbeiten']
}
}
}
});
const chartTranslator = new Translator({
languagePack: {
domain: 'charts',
locale_data: {
superset: {
'': { domain: 'charts', lang: 'de', plural_forms: 'nplurals=2; plural=(n != 1)' },
'Chart': ['Diagramm'],
'Visualization': ['Visualisierung']
}
}
}
});import { configure, resetTranslation, t } from '@superset-ui/core';
async function switchLanguage(locale: Locale) {
// Reset current translations
resetTranslation();
// Load new language pack
const languagePack = await import(`../locales/${locale}.json`);
// Configure with new language
configure({ languagePack });
// Trigger UI re-render
dispatchLanguageChangeEvent();
}
// Usage
switchLanguage('fr').then(() => {
console.log(t('Welcome')); // "Bienvenue"
});// Use descriptive, hierarchical keys
const translations = {
'dashboard.title': ['Panel de Control'],
'dashboard.actions.save': ['Guardar'],
'dashboard.actions.delete': ['Eliminar'],
'chart.config.title': ['Configuración del Gráfico'],
'chart.config.axes.x_label': ['Etiqueta del Eje X']
};
// Avoid dynamic key generation
// ❌ Bad
const dynamicKey = `message.${type}.${status}`;
const text = t(dynamicKey);
// ✅ Good
const messageMap = {
'success': t('message.success'),
'error': t('message.error'),
'warning': t('message.warning')
};
const text = messageMap[type];// Lazy load translations for large applications
const loadTranslations = async (locale: Locale) => {
const { default: translations } = await import(`../i18n/${locale}.json`);
return translations;
};
// Memoize translated strings in components
const TranslatedComponent = React.memo(() => {
const title = useMemo(() => t('Dashboard Title'), []);
const description = useMemo(() => t('Dashboard Description'), []);
return <div>{title}: {description}</div>;
});Install with Tessl CLI
npx tessl i tessl/npm-superset-ui--core@0.18.1