Skip to main content

Internationalization (i18n)

Audience: End users and non-technical stakeholders Last Updated: 2026-04-05 Version: 2.0.0


Overview

Llamafin is available in 18 languages, making your music library accessible to users around the world. The application supports runtime language switching, meaning you can change the language without restarting the app. Every label, message, button, and interface element is translated, providing a fully localized experience.

The translation system is designed to be smart and respectful of your preferences: it remembers your language choice, detects your browser language on first run, and loads translations efficiently in the background.


Key Concepts

1. Supported Languages

Llamafin supports the following languages:

CodeLanguageCodeLanguage
enEnglishptPortuguês
deDeutschplPolski
esEspañolsvSvenska
frFrançaisnoNorsk
itItalianodaDansk
ruРусскийfiSuomi
zh中文isÍslenska
ja日本語trTürkçe
nlNederlandsafAfrikaans
zuisiZulu

2. Translation Domains

The application's text content is organised into 29 translation domains, each covering a specific area of the app:

DomainCovers
AppApplication-level strings, loading messages
CommonShared strings used across multiple screens
LoginLogin page labels, instructions, errors
LibraryAlbum, artist, song, playlist, genre, folder browsing
PlayerPlayback controls, queue, player views
SettingsAll settings labels and descriptions
DownloadsDownload management strings
AudioAudio engine and equalizer labels
ErrorsError messages and descriptions
NetworkNetwork status messages
SearchSearch page labels and results
HomeHome page sections and labels
NotificationsPush notification text
DJDJ mode and auto-play strings
ConnectDevice pairing and P2P strings
Car UIAndroid Auto / CarPlay interface
VisualiserAudio visualizer labels
LyricsLyrics display strings
And moreAuth, sessions, sleep timer, offline mode, etc.

3. Language Detection

When you first open Llamafin, the app determines your preferred language using a priority system:

PriorityMethodBehaviour
1Your stored preferenceIf you previously selected a language, it is used
2Browser languageIf no stored preference, the app detects your browser's language and uses it (if supported)
3English (default)If your browser language is not supported, English is used

One-time detection: Browser language detection happens only once. After the first run, your choice is saved and respected on all future launches.

4. Runtime Language Switching

You can change the language at any time from Settings > Language. When you select a new language:

  1. Translations for the new language are loaded immediately
  2. The entire interface updates without requiring an app restart
  3. Your choice is saved automatically for future sessions

5. Translation Files

Translation content is stored as JSON files organised by language and domain. Each language has 29 JSON files, one per domain. These files are loaded from the app's assets when you switch languages.

6. Interpolation

Some translated strings include placeholders that are filled in dynamically:

  • "Are you sure you want to delete {{itemName}} from your server?" -- {{itemName}} is replaced with the actual item name
  • "{{trackName}} is already playing." -- {{trackName}} is replaced with the current track

This allows translations to include dynamic content while maintaining correct grammar and word order in every language.

7. Missing Translation Handling

If a translation key is missing in your selected language, the app displays the key name itself (e.g., login.TITLE). This is a safety measure to ensure the interface never shows blank text.

8. Translation Management

The project uses a sophisticated translation pipeline that supports multiple translation providers:

ProviderDescription
Local LLMAI-powered translation using a local language model (default)
Google TranslateGoogle Cloud Translation API (optional)
DeepLDeepL API (optional)

This pipeline includes validation, manual edit tracking, and progress tracking to ensure translation quality.


Configuration

Language Settings

SettingLocationDescription
LanguageSettings > LanguageSelect your preferred language from the list of 18 supported languages

Language Picker

The language selection page shows:

  • Your current language at the top of the list
  • All available languages sorted alphabetically (after your current language)
  • Native language names (e.g., "Deutsch" not "German")
  • Country flag icons for visual identification

When you tap a language, the interface switches immediately.


How It Works

Startup Language Selection

1. App launches

2. Loads your saved settings from storage

3. Checks: Do you have a stored language preference?

├── Yes ──→ Use your stored language

└── No ──→ Detect browser language

├── Supported? ──→ Use it and save to settings

└── Not supported? ──→ Use English and save to settings

4. Loads all 29 translation files for the selected language (in parallel)

5. Interface fully translated and ready to use

Language Switching

1. You select a new language in Settings > Language

2. App immediately calls translate.use(newLanguage)

3. 29 translation files loaded in parallel from assets

4. Every translated element in the UI updates instantly

5. Your language choice is saved to settings (debounced by 1 second)

6. Next time you open the app, your choice is restored

Translation Loading

You switch to Spanish (es)

App requests 29 translation files in parallel:
├── /assets/i18n/es/app.json
├── /assets/i18n/es/auth.json
├── /assets/i18n/es/login.json
├── /assets/i18n/es/library.json
├── ... (all 29 domains)

All responses merged into a single translation object

UI updates with Spanish text

Integration with Other Features

Featurei18n IntegrationDescription
SettingsLanguage preference storageYour language choice saved in settings state
AlertsNetwork alerts, confirmationsAll alert banners and confirmation dialogues translated
Toast MessagesSuccess, error, info messagesAll notification toasts translated
LoginLogin page labels, errorsAuthentication UI fully localized
LibraryAlbum, artist, genre labelsAll library browsing strings translated
PlayerQueue, controls, viewsPlayer interface strings translated
DownloadsDownload status, progressDownload management strings translated
Media SessionLock screen, Car UIMedia session metadata translated (artist, album names use original values)

Error Handling & Reliability

Translation Load Failures

ScenarioBehaviour
Translation file missing (404)Key name displayed instead of translation
Malformed JSON fileTranslation file skipped; other domains still load
Network unavailable during switchCurrent language retained; no change applied

Language Detection Issues

ScenarioBehaviour
Browser language not supportedEnglish used as fallback and saved to settings
Browser language detection failsEnglish used as default and saved to settings

Missing Translation Keys

ScenarioBehaviour
Key exists in English but not in your languageKey name displayed (e.g., settings.ABOUT_SECTION)
Key has typo in translation fileTypo displayed as-is

Translation Validation

The project includes automated validation scripts that:

  • Check for missing keys compared to the English source
  • Detect extra keys that don't exist in the source
  • Validate JSON structure
  • Track manually edited keys that should not be auto-overwritten

Technical Specifications

SpecificationValueDescription
Supported Languages18Full language coverage
Translation Domains29Separate JSON files per language
Translation Engine@ngx-translate/coreRuntime translation library
Loading StrategyParallel HTTP requestsAll 29 files load simultaneously
Default LanguageEnglishFallback when no preference detected
Language PersistenceIndexedDB (via Settings)Survives app restarts
Language SwitchRuntime (no reload)Instant language change
Interpolation{{param}} syntaxDynamic content in translations
Missing Key BehaviourDisplays key stringSafety fallback for missing translations
Browser DetectionOne-time onlyDetected language saved to settings
Settings Save Debounce1 secondBatches rapid setting changes
Translation ScriptsLLM, Google, DeepLMultiple translation providers available
Translation ValidationAutomated CLI scriptsKey comparison, JSON validation, progress tracking

Known Limitations

Right-to-Left (RTL) Languages

  • No RTL support: The app does not support right-to-left languages such as Arabic or Hebrew. The interface layout is always left-to-right.
  • RTL languages not in supported list: Arabic (ar) and Hebrew (he) are not among the 18 supported languages.

Date, Number, and Currency Formatting

  • No locale-specific formatting: The app relies on the browser's built-in Intl APIs for date, number, and currency formatting. These are not integrated with the i18n system.
  • Custom pipes: The app provides custom pipes for specific formatting (truncate, ticks-to-time, bytes, short numbers) but these are not locale-aware.

Pluralization

  • Simple interpolation only: The translation system uses {{param}} placeholders but does not support ICU message format or language-specific pluralization rules.
  • Manual handling: Plural forms (e.g., "1 song" vs "2 songs") must be handled manually in the application code, not through translation keys.

Translation Caching

  • Browser cache only: Translation files are cached by the browser's HTTP cache but there is no specific service worker caching strategy for translations.
  • No preloading: Translations are only loaded when you switch languages. There is no preloading of other languages in the background.

Compile-Time i18n

  • Runtime only: The app uses runtime translation loading, not Angular's compile-time i18n. This means:
    • A single build works for all languages
    • No tree-shaking of unused languages (all translation files are included in the app)
    • Translation files are fetched over HTTP at runtime