4.5 KiB
Contributing Translations to Handy
Thank you for helping translate Handy! This guide explains how to add or improve translations.
Quick Start
- Fork the repository
- Check the currently supported languages. For an existing language, edit its translation file; for a new language, copy the English translation file to a new language folder
- Translate the values (not the keys!)
- Submit a pull request
File Structure
Translation files are located in:
src/i18n/locales/
├── en/
│ └── translation.json # English (source)
├── vi/
│ └── translation.json # Vietnamese
├── fr/
│ └── translation.json # French
└── [your-language]/
└── translation.json # Your contribution!
Adding a New Language
Step 1: Create the Language Folder
Create a new folder using the ISO 639-1 language code:
mkdir src/i18n/locales/[language-code]
Examples:
defor Germanesfor Spanishjafor Japanesezhfor Chinesekofor Koreanptfor Portuguese
Step 2: Copy the English File
cp src/i18n/locales/en/translation.json src/i18n/locales/[language-code]/translation.json
Step 3: Translate the Values
Open the file and translate only the values (right side), not the keys (left side):
{
"sidebar": {
"general": "General", // ← Translate this value
"advanced": "Advanced", // ← Translate this value
...
}
}
Important:
- Keep all keys exactly the same
- Preserve any
{{variables}}in the text (e.g.,{{error}},{{model}}) - Keep the JSON structure and formatting intact
Step 4: Register Your Language
Edit src/i18n/languages.ts and add your language metadata:
export const LANGUAGE_METADATA: Record<
string,
{ name: string; nativeName: string }
> = {
en: { name: "English", nativeName: "English" },
es: { name: "Spanish", nativeName: "Español" },
fr: { name: "French", nativeName: "Français" },
vi: { name: "Vietnamese", nativeName: "Tiếng Việt" },
de: { name: "German", nativeName: "Deutsch" }, // ← Add your language
};
Step 5: Test Your Translation
- Run the app:
bun run tauri dev - Go to Settings → General → App Language
- Select your language
- Verify all text displays correctly
Step 6: Submit a Pull Request
- Commit your changes
- Push to your fork
- Open a pull request with:
- Language name in the title (e.g., "Add German translation")
- Any notes about the translation
Improving Existing Translations
Found a typo or better translation?
- Edit the relevant
translation.jsonfile - Submit a PR with a brief description of the change
Translation Guidelines
Do:
- Use natural, native-sounding language
- Keep translations concise (UI space is limited)
- Match the tone of the English text (friendly, clear)
- Preserve technical terms when appropriate (e.g., "API", "GPU")
Don't:
- Translate brand names (Handy, transcribe.cpp, ggml, OpenAI)
- Change or remove
{{variables}} - Modify JSON keys
- Add extra spaces or formatting
Handling Variables
Some strings contain variables like {{error}} or {{model}}. Keep these exactly as-is:
// English
"downloadModel": "Failed to download model: {{error}}"
// French (correct)
"downloadModel": "Échec du téléchargement du modèle : {{error}}"
// French (incorrect - don't translate the variable!)
"downloadModel": "Échec du téléchargement du modèle : {{erreur}}"
Handling Plurals
Some languages have complex plural rules. For now, use a general form that works for all cases. We may add proper plural support in the future.
Questions?
- Open an issue on GitHub
- Join the discussion in existing translation PRs
Currently Supported Languages
See language metadata for the current language names and codes, and locale folders for their translation files. The app discovers supported languages from these folders.
English is the source language. Existing translations may still need corrections or updates.
Requested Languages
We welcome additional languages that are not yet in the locale folders, as well as improvements to existing translations.
Thank you for making Handy accessible to more people around the world!