Now.js Framework Documentation
I18nManager
I18nManager
Overview
I18nManager is the internationalization (i18n) system in Now.js Framework. It supports multi-language translations and locale management.
When to use:
- Need multi-language support
- Need dynamic language switching
- Need to translate UI elements
- Need locale-aware formatting
Why use it:
- ✅ File-based translations (JSON)
- ✅ Dynamic locale switching
- ✅ HTML attribute support (
data-i18n) - ✅ Parameter interpolation
- ✅ Fallback locale
- ✅ Browser locale detection
- ✅ LocalStorage persistence
Basic Usage
Initialization
await I18nManager.init({
enabled: true,
defaultLocale: 'en',
availableLocales: ['en', 'th', 'ja'],
useBrowserLocale: true
});HTML Declarative
<!-- Simple translation -->
<h1 data-i18n="welcome">Welcome</h1>
<!-- With parameters -->
<p data-i18n="greeting" data-i18n-params='{"name": "John"}'>
Hello, John!
</p>
<!-- Attribute translation -->
<input data-i18n-placeholder="searchPlaceholder" placeholder="Search...">
<button data-i18n-title="saveTooltip" title="Save">💾</button>JavaScript API
// Translate
const text = I18nManager.translate('welcome');
// => 'Welcome' (if locale is 'en')
// With parameters
const greeting = I18nManager.translate('greeting', { name: 'John' });
// => 'Hello, John!' (if locale is 'en')
// Change locale
await I18nManager.setLocale('th');Translation Files
Create JSON files in /translations/:
/translations/
en.json
th.json
ja.jsonen.json
{
"welcome": "Welcome",
"greeting": "Hello, {name}!",
"nav": {
"home": "Home",
"about": "About",
"contact": "Contact"
},
"buttons": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete"
}
}th.json
{
"welcome": "ยินดีต้อนรับ",
"greeting": "สวัสดี {name}!",
"nav": {
"home": "หน้าแรก",
"about": "เกี่ยวกับ",
"contact": "ติดต่อ"
},
"buttons": {
"save": "บันทึก",
"cancel": "ยกเลิก",
"delete": "ลบ"
}
}Data Attributes
| Attribute | Description |
|---|---|
data-i18n |
Translation key for text content |
data-i18n-params |
JSON parameters for interpolation |
data-i18n-placeholder |
Translation key for placeholder |
data-i18n-title |
Translation key for title |
data-i18n-aria-label |
Translation key for aria-label |
data-i18n-[attr] |
Translation key for any attribute |
<input type="text"
data-i18n-placeholder="search.placeholder"
data-i18n-aria-label="search.ariaLabel">
<img data-i18n-alt="images.logo.alt" src="/logo.png">Configuration
await I18nManager.init({
// Enable i18n
enabled: true,
// Default locale
defaultLocale: 'en',
// Available locales
availableLocales: ['en', 'th', 'ja', 'zh'],
// Storage key for persisting locale
storageKey: 'app_lang',
// Use browser's locale if available
useBrowserLocale: true,
// Skip English lookup (use key as fallback)
noTranslateEnglish: true
});API Reference
I18nManager.setLocale(locale, force?)
Change language
| Parameter | Type | Description |
|---|---|---|
locale |
string | Locale code (e.g., 'th', 'en') |
force |
boolean | Force reload translations |
Returns: Promise<void>
await I18nManager.setLocale('th');I18nManager.getCurrentLocale()
Get current locale
Returns: string
const locale = I18nManager.getCurrentLocale();
// 'en'I18nManager.translate(key, params?, locale?)
Translate text
| Parameter | Type | Description |
|---|---|---|
key |
string | Translation key (dot notation supported) |
params |
object | Interpolation parameters |
locale |
string | Specific locale (optional) |
Returns: string
// Simple
I18nManager.translate('welcome');
// Nested key
I18nManager.translate('nav.home');
// With params
I18nManager.translate('greeting', { name: 'John' });
// Specific locale
I18nManager.translate('welcome', {}, 'ja');I18nManager.updateElements(container?)
Update translations in DOM
| Parameter | Type | Description |
|---|---|---|
container |
HTMLElement | Container to update (default: document) |
// Update all elements
I18nManager.updateElements();
// Update specific container
I18nManager.updateElements(document.getElementById('modal'));I18nManager.hasTranslation(key, locale?)
Check if translation exists
| Parameter | Type | Description |
|---|---|---|
key |
string | Translation key |
locale |
string | Specific locale (optional) |
Returns: boolean
I18nManager.getTranslations(locale?)
Get all translations
Returns: object
Events
| Event | When Triggered | Detail |
|---|---|---|
i18n:locale-changed |
Language changed | {locale, previous} |
i18n:translations-loaded |
Translations loaded | {locale} |
EventManager.on('i18n:locale-changed', (data) => {
console.log(`Language changed to: ${data.locale}`);
});Real-World Examples
Language Switcher
<select id="language-select">
<option value="en">English</option>
<option value="th">ไทย</option>
<option value="ja">日本語</option>
</select>
<script>
const select = document.getElementById('language-select');
// Set current value
select.value = I18nManager.getCurrentLocale();
// Handle change
select.addEventListener('change', async (e) => {
await I18nManager.setLocale(e.target.value);
});
</script>Dynamic Content Translation
// After loading dynamic content
async function loadProducts() {
const products = await ApiService.get('/api/products');
const container = document.getElementById('products');
container.innerHTML = products.map(p => `
<div class="product">
<h3>${p.name}</h3>
<button data-i18n="buttons.addToCart">Add to Cart</button>
</div>
`).join('');
// Update translations for new elements
I18nManager.updateElements(container);
}Pluralization
// en.json
{
"items": {
"zero": "No items",
"one": "1 item",
"other": "{count} items"
}
}function translatePlural(key, count) {
const pluralKey = count === 0 ? 'zero' : count === 1 ? 'one' : 'other';
return I18nManager.translate(`${key}.${pluralKey}`, { count });
}
translatePlural('items', 0); // 'No items'
translatePlural('items', 1); // '1 item'
translatePlural('items', 5); // '5 items'Common Pitfalls
⚠️ 1. Wait for Translations to Load
// ❌ Using before init
I18nManager.translate('key');
// ✅ Wait for init
await I18nManager.init({ enabled: true });
I18nManager.translate('key');⚠️ 2. Update Dynamic Content
// ❌ Forget to update after adding content
container.innerHTML = newContent;
// ✅ Call updateElements
container.innerHTML = newContent;
I18nManager.updateElements(container);⚠️ 3. Fallback Keys
// If key not found, key is used as fallback
I18nManager.translate('missing.key');
// => 'missing.key'
// Add default locale fallback
// en.json should have all keysRelated Documentation
- Utils.date - Date formatting with locale
- TemplateManager - Template rendering