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.

js
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).

PropertyTypeDescription
basePathstringRoot URL path for loading JSON translation files. Default: '/i18n'.
defaultLangstringLanguage code used as the active language. Default: 'en'.
fallbackLangstringLanguage 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.

Aura.i18n.configure(config: Partial<I18nConfig>): void
ParamTypeDescription
configPartial<I18nConfig>Object with optional basePath, defaultLang, and fallbackLang fields.
js
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.

Aura.i18n.load(lang: string): Promise<void>
ParamTypeDescription
langstringLanguage code to load and activate (e.g. 'en', 'fr', 'ar').
js
// 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.

Aura.i18n.load(lang: string): Promise<void>

Alternatively, use configure() to set the language synchronously if translations are already loaded:

Aura.i18n.configure({ defaultLang: lang }): void
js
// 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.

Aura.i18n.getLang(): string

This method takes no parameters.

js
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.

Aura.i18n.t(key: string, params?: Record<string, string | number>): string
ParamTypeDescription
keystringDot-notation translation key (e.g. 'nav.home', 'errors.notFound').
paramsRecord<string, string | number>Optional interpolation values. Replaces {name} placeholders in the translated string.
json
// en.json
{
  "nav": {
    "home": "Home",
    "profile": "Profile"
  },
  "greeting": "Hello, {name}! You have {count} messages."
}
js
// 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.

Aura.i18n.plural(key: string, count: number, params?: Record<string, string | number>): string
ParamTypeDescription
keystringBase translation key. Suffixes _zero, _one, _other (etc.) are appended automatically.
countnumberThe count used to determine which plural form to use.
paramsRecord<string, string | number>Optional additional interpolation values (merged with { count }).
json
// en.json
{
  "items_zero": "No items",
  "items_one": "One item",
  "items_other": "{count} items"
}
js
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.

Aura.i18n.formatNumber(n: number, options?: Intl.NumberFormatOptions): string
ParamTypeDescription
nnumberThe number to format.
optionsIntl.NumberFormatOptionsOptional formatting options (style, currency, minimumFractionDigits, etc.).
js
// 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).

Aura.i18n.formatDate(date: Date | number, options?: Intl.DateTimeFormatOptions): string
ParamTypeDescription
dateDate | numberA Date object or Unix timestamp in milliseconds.
optionsIntl.DateTimeFormatOptionsOptional formatting options (dateStyle, timeStyle, weekday, year, month, day, etc.).
js
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.

Aura.i18n.formatRelative(date: Date | number, options?: Intl.RelativeTimeFormatOptions): string
ParamTypeDescription
dateDate | numberA Date object or Unix timestamp in milliseconds.
optionsIntl.RelativeTimeFormatOptionsOptional formatting options (numeric, style). Defaults to automatic.
js
// 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.

Aura.i18n.isRTL(): boolean

This method takes no parameters.

js
// 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.

Aura.i18n.translateDOM(container: Element): void
ParamTypeDescription
containerElementThe DOM element to scan for data-i18n attributes. All descendants are translated.
html
<!-- 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>
js
// 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