Internationalization (i18n)
The Lovina Chat SDK supports 3 languages out of the box. All UI strings can be overridden without creating a full translation file.
Supported Locales
| Code | Language | Direction |
|---|---|---|
en | English | LTR |
id | Bahasa Indonesia (default) | LTR |
ar | Arabic | RTL |
Setting the Locale
At Initialization
window.lovinaSettings = {
locale: 'en',
};
Auto-Detect from Browser
window.lovinaSettings = {
useBrowserLanguage: true, // Uses navigator.language
};
The SDK extracts the base language code from navigator.language (e.g., pt-BR becomes pt) and checks it against supported locales. If a match is found, it overrides the locale setting.
At Runtime with setLocale
Change the language at any time. The UI updates immediately:
window.$lovina.setLocale('id'); // Switch to Indonesian
window.$lovina.setLocale('en'); // Switch to English
window.$lovina.setLocale('ar'); // Switch to Arabic
Locale Resolution Order
The SDK determines the active locale using this priority:
- Explicit
localesetting (highest priority) - Browser language (if
useBrowserLanguageistrueand a match exists) - Default:
'id'(Indonesian)
Custom Text Overrides
Override any UI string without creating a full translation file. Overrides are provided via the texts configuration and take priority over built-in translations.
window.lovinaSettings = {
locale: 'en',
texts: {
header: {
title: 'Acme Help',
online: "We're here",
offline: 'Leave a message',
},
welcome: {
title: 'Hello!',
message: 'Ask us anything about your order.',
},
input: {
placeholder: 'Describe your issue...',
},
prechat: {
title: 'Quick question first',
name: 'Full name',
email: 'Work email',
submit: 'Connect me',
},
poweredBy: 'Powered by Acme',
},
};
Resolution order:
texts (overrides) --> built-in locale file --> English fallback
(highest priority) (selected locale) (always available)
Full Translation Key Reference
header.title Chat header title
header.online Online status text
header.offline Offline status text
header.typing Typing indicator text
header.newConversation "New chat" button label
header.conversationHistory "Past conversations" label
welcome.title Welcome screen title
welcome.message Welcome screen message
input.placeholder Message input placeholder
input.send Send button label
input.voiceInput Voice input button label
messages.sent "Sent" status label
messages.delivered "Delivered" status label
messages.read "Read" status label
messages.sending "Sending..." label
messages.failed Failed to send message
messages.today "Today" date separator
messages.yesterday "Yesterday" date separator
conversation.resolved Conversation resolved message
conversation.endChat End chat button label
conversation.endChatConfirm End chat confirmation prompt
conversation.cancel Cancel button label
conversation.confirm Confirm button label
conversation.newMessages "New messages" indicator
conversation.scrollToBottom Scroll to bottom label
prechat.title Pre-chat form title
prechat.name Name field label
prechat.email Email field label
prechat.message Message field label
prechat.submit Submit button label
status.connecting Connecting status text
status.reconnecting Reconnecting status text
status.offline Offline status text
poweredBy Footer "Powered by" text
RTL Support
Arabic (ar) and other RTL languages are detected automatically. When an RTL locale is active, the widget layout flips:
- Message bubbles align to the opposite side.
- Input actions and header icons reverse direction.
- The widget position flips (right becomes left).
No additional configuration is required. The SDK sets the dir="rtl" attribute on the widget container automatically.
Supported RTL locales: ar.
Adding a New Locale
To contribute a new locale to the SDK:
- Create a new JSON file in the
src/widget/i18n/locales/directory (e.g.,tr.jsonfor Turkish). - Copy the structure from
en.jsonand translate all values. - Register the new locale in the i18n manager.
Example locale file structure:
{
"header": {
"title": "Destek",
"online": "Cevrimici",
"offline": "Cevrimdisi",
"typing": "Yaziyor...",
"newConversation": "Yeni sohbet",
"conversationHistory": "Gecmis konusmalar"
},
"welcome": {
"title": "Merhaba!",
"message": "Size nasil yardimci olabiliriz?"
},
"input": {
"placeholder": "Bir seyler yazin...",
"send": "Gonder"
}
}
Locale files are lazy-loaded -- only the active locale is fetched, keeping the initial bundle small.
Date and Time Formatting
The SDK uses Intl.RelativeTimeFormat and Intl.DateTimeFormat for locale-aware timestamps:
- Under 1 minute: "Just now"
- Under 1 hour: "2 minutes ago" / "2 menit yang lalu" (id)
- Same day: "2:34 PM" formatted per locale
- Older: "Jun 15" formatted per locale