i18n
A complete internationalization module with JSON-based translation loading, interpolated string parameters,
pluralization rules, number/date/relative-time formatting via the Intl API, RTL detection,
and automatic DOM translation using data-i18n attributes.
Quick Start
Configure the i18n module, load a language file, and start translating strings and DOM elements.
import Aura from 'aurajs'; // Configure i18n Aura.i18n.configure({ basePath: '/i18n', defaultLang: 'en', fallbackLang: 'en' }); // Load a language (fetches /i18n/en.json) await Aura.i18n.load('en'); // Translate a key const greeting = Aura.i18n.t('home.welcome', { name: 'Alice' }); // en.json: { "home": { "welcome": "Hello, {name}!" } } // => "Hello, Alice!" // Auto-translate all [data-i18n] elements Aura.i18n.translateDOM(document.body);
Types
I18nConfig
Configuration object accepted by configure(). All fields are optional (partial).
| Property | Type | Description |
|---|---|---|
| basePath | string | Root URL path for loading JSON translation files. Default: '/i18n'. |
| defaultLang | string | Language code used as the active language. Default: 'en'. |
| fallbackLang | string | Language code used when a key is not found in the active language. Default: 'en'. |
configure() core
Update the i18n configuration. Only provided fields are changed.
| Param | Type | Description |
|---|---|---|
| config | Partial<I18nConfig> | Object with optional basePath, defaultLang, and fallbackLang fields. |
Aura.i18n.configure({ basePath: '/locales', defaultLang: 'fr', fallbackLang: 'en' });
load() core
Fetch a JSON translation file from basePath/lang.json and set it as the active language. If the language has already been loaded, it is served from the internal cache. After loading, the active language is switched to the given code.
| Param | Type | Description |
|---|---|---|
| lang | string | Language code to load and activate (e.g. 'en', 'fr', 'ar'). |
// Load and activate English await Aura.i18n.load('en'); // Switch to French await Aura.i18n.load('fr'); // Pre-load multiple languages await Promise.all([ Aura.i18n.load('en'), Aura.i18n.load('fr'), Aura.i18n.load('de') ]);
setLang() core
Switch the active language. This is equivalent to calling load(), which both fetches (if needed) and sets the active language. You can also add translations manually and configure the default language.
Alternatively, use configure() to set the language synchronously if translations are already loaded:
// Switch language (loads if needed) await Aura.i18n.load('de'); // Or add translations manually and switch synchronously Aura.i18n.addTranslations('es', { greeting: 'Hola, {name}!' }); Aura.i18n.configure({ defaultLang: 'es' }); // Re-translate the DOM after switching Aura.i18n.translateDOM(document.body);
getLang() utility
Return the currently active language code.
This method takes no parameters.
const lang = Aura.i18n.getLang(); console.log(lang); // "en" // Set the HTML lang attribute document.documentElement.lang = Aura.i18n.getLang();
t() core
Translate a key to the active language. Supports dot-notation for nested keys and {param} interpolation. Falls back to the fallback language if the key is not found in the active language. Returns the raw key string if no translation exists in either language.
| Param | Type | Description |
|---|---|---|
| key | string | Dot-notation translation key (e.g. 'nav.home', 'errors.notFound'). |
| params | Record<string, string | number> | Optional interpolation values. Replaces {name} placeholders in the translated string. |
// en.json { "nav": { "home": "Home", "profile": "Profile" }, "greeting": "Hello, {name}! You have {count} messages." }
// Simple key Aura.i18n.t('nav.home'); // => "Home" // With interpolation Aura.i18n.t('greeting', { name: 'Alice', count: 5 }); // => "Hello, Alice! You have 5 messages." // Missing key returns the key itself Aura.i18n.t('missing.key'); // => "missing.key"
plural() core
Translate a key with pluralization. Looks up suffixed keys (key_zero, key_one, key_other) based on the count. Uses the default rule (0 = zero, 1 = one, else = other) unless a custom plural rule is set with setPluralRule(). The count value is automatically available as an interpolation parameter.
| Param | Type | Description |
|---|---|---|
| key | string | Base translation key. Suffixes _zero, _one, _other (etc.) are appended automatically. |
| count | number | The count used to determine which plural form to use. |
| params | Record<string, string | number> | Optional additional interpolation values (merged with { count }). |
// en.json { "items_zero": "No items", "items_one": "One item", "items_other": "{count} items" }
Aura.i18n.plural('items', 0); // => "No items" Aura.i18n.plural('items', 1); // => "One item" Aura.i18n.plural('items', 42); // => "42 items" // Custom plural rule for a language Aura.i18n.setPluralRule('ar', (n) => { if (n === 0) return 'zero'; if (n === 1) return 'one'; if (n === 2) return 'two'; if (n >= 3 && n <= 10) return 'few'; if (n >= 11 && n <= 99) return 'many'; return 'other'; });
formatNumber() formatting
Format a number using Intl.NumberFormat with the active language locale. Supports all standard Intl.NumberFormatOptions including currency, percentage, and unit formatting.
| Param | Type | Description |
|---|---|---|
| n | number | The number to format. |
| options | Intl.NumberFormatOptions | Optional formatting options (style, currency, minimumFractionDigits, etc.). |
// Basic number formatting (locale-aware) Aura.i18n.formatNumber(1234567.89); // en => "1,234,567.89" // de => "1.234.567,89" // Currency Aura.i18n.formatNumber(99.99, { style: 'currency', currency: 'USD' }); // => "$99.99" // Percentage Aura.i18n.formatNumber(0.85, { style: 'percent' }); // => "85%"
formatDate() formatting
Format a date using Intl.DateTimeFormat with the active language locale. Accepts a Date object or a Unix timestamp (milliseconds).
| Param | Type | Description |
|---|---|---|
| date | Date | number | A Date object or Unix timestamp in milliseconds. |
| options | Intl.DateTimeFormatOptions | Optional formatting options (dateStyle, timeStyle, weekday, year, month, day, etc.). |
const now = new Date(); // Default formatting Aura.i18n.formatDate(now); // en => "3/17/2026" // Long format Aura.i18n.formatDate(now, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); // en => "Tuesday, March 17, 2026" // From a timestamp Aura.i18n.formatDate(1774000000000, { dateStyle: 'medium', timeStyle: 'short' });
formatRelative() formatting
Format a date as a human-readable relative time string (e.g. "5 minutes ago", "in 3 hours") using Intl.RelativeTimeFormat. Automatically selects the best unit (seconds, minutes, hours, or days) based on the time difference from now.
| Param | Type | Description |
|---|---|---|
| date | Date | number | A Date object or Unix timestamp in milliseconds. |
| options | Intl.RelativeTimeFormatOptions | Optional formatting options (numeric, style). Defaults to automatic. |
// 30 seconds ago Aura.i18n.formatRelative(Date.now() - 30000); // => "30 seconds ago" // 2 hours from now Aura.i18n.formatRelative(Date.now() + 7200000); // => "in 2 hours" // 3 days ago const threeDaysAgo = new Date(); threeDaysAgo.setDate(threeDaysAgo.getDate() - 3); Aura.i18n.formatRelative(threeDaysAgo); // => "3 days ago" // With short style Aura.i18n.formatRelative(Date.now() - 60000, { style: 'short' }); // => "1 min. ago"
isRTL() utility
Check whether the active language is a right-to-left script. Returns true for Arabic, Hebrew, Farsi, Urdu, Pashto, Sindhi, Yiddish, and Divehi.
This method takes no parameters.
// Set document direction based on language document.documentElement.dir = Aura.i18n.isRTL() ? 'rtl' : 'ltr'; // Conditionally load RTL stylesheet if (Aura.i18n.isRTL()) { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = '/css/rtl.css'; document.head.appendChild(link); }
translateDOM() core
Automatically translate all elements within a container that have a data-i18n attribute. Also handles data-i18n-placeholder and data-i18n-title attributes for input placeholders and tooltip titles. Interpolation parameters are read from data-i18n-* attributes.
| Param | Type | Description |
|---|---|---|
| container | Element | The DOM element to scan for data-i18n attributes. All descendants are translated. |
<!-- Text content translation --> <h1 data-i18n="home.title"></h1> <!-- With interpolation parameters --> <p data-i18n="greeting" data-i18n-name="Alice"></p> <!-- Placeholder translation --> <input data-i18n-placeholder="search.placeholder" /> <!-- Title (tooltip) translation --> <button data-i18n="actions.save" data-i18n-title="actions.save.tooltip"></button>
// Translate the entire page Aura.i18n.translateDOM(document.body); // Or translate a specific section after dynamic rendering const modal = document.querySelector('.modal'); Aura.i18n.translateDOM(modal); // Note: renderTo() calls translateDOM() automatically