Skip to content

Translations (i18n)

This page is for contributors adding or improving translations. Picking a language as an end user? See Languages instead.

What's translated

  • The app UI is translated. 19 locales currently ship
  • The docs (what you're reading right now) are currently English-only
  • Game metadata comes from metadata providers (IGDB, ScreenScraper) and their localisation varies per title

Tech stack

  • Library: vue-i18n
  • Format: JSON, one file per feature per locale
  • Location: frontend/src/locales/<locale>/

en_US/ is the reference, and other locales must always be kept complete and current, which is validated by CI. When in doubt, copy the English key and change the value.

Adding keys to an existing locale

If the English UI has a string that isn't translated in your locale, fill it in:

  1. Fork rommapp/romm
  2. Open frontend/src/locales/en_US/*.json and find the untranslated key
  3. Open the corresponding file in frontend/src/locales/<your-locale>/*.json
  4. Add the key with your translation
  5. Open a pull request

Example

en_US/common.json:

{
    "scan": "Scan",
    "continue_playing": "Continue Playing"
}

fr_FR/common.json before:

{
    "scan": "Analyser"
}

After your contribution:

{
    "scan": "Analyser",
    "continue_playing": "Continuer à jouer"
}

Adding a new locale

If the language you want isn't in the dropdown yet:

  1. Pick the locale code in BCP 47 form (de_DE, pt_BR, zh_TW)
  2. Copy frontend/src/locales/en_US/ to frontend/src/locales/<your-locale>/
  3. Start translating the most-visible strings (menu, navigation, home dashboard), and work your way through the rest as you have time
  4. Register the locale in the index file (look in frontend/src/locales/index.ts)
  5. Verify your locale appears in the in-app language picker.
  6. Open a pull request

Tip

AI is excellent at scaffolding a new locale, but be sure to review and edit the output for accuracy and style.

Style guidance

Tone

Match the source tone:

  • Conversational but not too casual. "Let's scan your library" is fine, but "Yo, scan your ROMs dude" isn't.
  • Active voice. "Scanning the library" reads better than "The library is being scanned".
  • Consistent formality. Pick tu/vous, formal/informal you, and so on, then stick with that choice across the entire locale.

Consistency

Use the same word for the same concept throughout. If you translate "Collection" one way at the top of a file, don't translate it differently three screens later.

Interpolations

vue-i18n uses {placeholder} syntax. Don't translate placeholder names.

{
    "hello_user": "Hello, {username}!",
    "n_games_found": "Found {count} games"
}

Pluralisation:

{
    "n_games_found": "No games found | {count} game found | {count} games found"
}

Pipe-separated forms: zero | one | more. Not every language has three, and vue-i18n's pluralisation docs cover per-language rules.

What not to translate

  • Proper nouns (RomM, IGDB, ScreenScraper, RetroAchievements)
  • Technical identifiers (env var names, config keys, URLs)
  • Code samples and filenames

Testing your translation

cd frontend && npm install && npm run dev

Open http://localhost:3000, pick your locale, and walk through the app to confirm strings appear correctly across major flows (browse, detail, admin, settings).

Tooling

We don't use a translation-management platform (Weblate, Crowdin, etc.), but we may add one if interest grows, so open an issue if you'd prefer that!