translation guide - nself-org/nchat GitHub Wiki
Welcome to the nself-chat translation community! This guide will help you contribute translations in your language.
- Make nself-chat accessible to speakers of your language
- Join a global community of contributors
- Get recognition for your contributions
- Help democratize team communication tools
Look in src/locales/ to see if your language folder exists:
- โ Exists โ Jump to Improving Existing Translations
- โ Doesn't exist โ Continue with Adding a New Language
Each language has 4 main files:
src/locales/[lang-code]/
โโโ common.json # Common UI strings (buttons, labels, errors)
โโโ chat.json # Chat-specific strings (messages, channels)
โโโ settings.json # Settings UI strings
โโโ admin.json # Admin dashboard strings
# Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/nself-chat.git
cd nself-chat
# Install dependencies
pnpm install
# Start development server
pnpm dev# Replace 'it' with your language code (ISO 639-1)
mkdir -p src/locales/itCommon language codes:
-
it- Italian -
ko- Korean -
nl- Dutch -
tr- Turkish -
hi- Hindi -
he- Hebrew -
pl- Polish -
sv- Swedish
cp src/locales/en/* src/locales/it/Edit src/lib/i18n/locales.ts and add your language:
export const SUPPORTED_LOCALES: Record<string, LocaleConfig> = {
// ... existing languages
it: {
code: 'it',
name: 'Italiano', // Native name
englishName: 'Italian', // English name
script: 'Latn', // Script: Latn (Latin), Arab, Hans, Cyrl, etc.
direction: 'ltr', // Direction: 'ltr' or 'rtl'
bcp47: 'it-IT', // BCP 47 language tag
flag: '๐ฎ๐น', // Flag emoji
dateFnsLocale: 'it', // date-fns locale identifier
numberLocale: 'it-IT', // Intl.NumberFormat locale
pluralRule: 'other', // Plural rule category (see below)
isComplete: false, // Set to true when 100% translated
completionPercent: 0, // Update as you translate
},
}Different languages have different plural rules:
-
other- English, Spanish, German, Italian, Portuguese (2 forms) -
few- Russian, Polish, Czech (3-4 forms) -
many- Arabic (6 forms) -
one- Chinese, Japanese, Korean (1 form)
Start with common.json (most important):
{
"app": {
"name": "nChat",
"tagline": "Piattaforma di Comunicazione del Team", // Translate
"loading": "Caricamento...", // Translate
"error": "Si รจ verificato un errore" // Translate
}
}Rules:
- โ Translate the values (right side)
- โ Don't change the keys (left side)
- โ
Keep variables like
{{name}}unchanged - โ Maintain proper JSON syntax
# Run the dev server
pnpm dev
# Open http://localhost:3000
# Go to Settings โ Language
# Select your language
# Navigate through the app to see your translations# Create a new branch
git checkout -b add-italian-translation
# Add your files
git add src/locales/it/
git add src/lib/i18n/locales.ts
# Commit your changes
git commit -m "feat(i18n): Add Italian translation"
# Push to your fork
git push origin add-italian-translation
# Create a Pull Request on GitHub# Check translation completion
node scripts/check-translations.js it
# Find missing keys
node scripts/find-missing-keys.js it- Edit the JSON files in
src/locales/[your-lang]/ - Translate missing or incorrect strings
- Test in the UI
- Submit a pull request
-
Translate for context
- Understand where the text appears in the UI
- Use natural, fluent language
- Match the app's friendly but professional tone
-
Preserve formatting
{ "welcome": "Benvenuto, {{name}}!" // โ Keep {{name}} } -
Handle plurals correctly
{ "messages_one": "{{count}} messaggio", "messages_other": "{{count}} messaggi" } -
Use appropriate formality
- Match the app's tone (usually informal "you")
- Be consistent across all translations
-
Test in the UI
- See how your translations look
- Check for text overflow
- Verify context makes sense
-
Don't use machine translation only
- Machine translation is a starting point
- Always review and refine
- Get feedback from other native speakers
-
Don't translate technical terms
- Keep: URL, API, OAuth, GraphQL, JSON, etc.
- Exception: If your language has widely accepted translation
-
Don't change interpolation variables
{ "welcome": "Benvenuto, {{nome}}!" // โ Wrong "welcome": "Benvenuto, {{name}}!" // โ Correct } -
Don't break JSON syntax
- Use proper quotes:
"not"or" - Escape special characters:
\",\\n - Validate JSON: Use an editor with syntax highlighting
- Use proper quotes:
English:
{
"app": {
"save": "Save",
"cancel": "Cancel"
}
}Italian:
{
"app": {
"save": "Salva",
"cancel": "Annulla"
}
}English:
{
"time": {
"ago": "{{time}} ago"
}
}Italian:
{
"time": {
"ago": "{{time}} fa"
}
}English:
{
"members": {
"count_one": "{{count}} member",
"count_other": "{{count}} members"
}
}Italian:
{
"members": {
"count_one": "{{count}} membro",
"count_other": "{{count}} membri"
}
}Arabic needs more plural forms:
{
"messages": {
"count_zero": "ูุง ุชูุฌุฏ ุฑุณุงุฆู",
"count_one": "ุฑุณุงูุฉ ูุงุญุฏุฉ",
"count_two": "ุฑุณุงูุชุงู",
"count_few": "{{count}} ุฑุณุงุฆู",
"count_many": "{{count}} ุฑุณุงูุฉ",
"count_other": "{{count}} ุฑุณุงูุฉ"
}
}If you're adding an RTL language (Arabic, Hebrew, Persian, Urdu):
-
Set direction in locale config
direction: 'rtl',
-
Test RTL layout
- Sidebar should be on the right
- Text should be right-aligned
- Icons should be mirrored
-
Report layout issues
- If something doesn't look right in RTL
- Open an issue with screenshots
- We'll fix the CSS
Some strings need RTL-specific handling:
{
"formatting": {
"bold": "**ุบุงู
ู**", // Arabic text between English markers
"example": "ู
ุซุงู: {{text}}" // RTL text with LTR variable
}
}Before submitting your translation, verify:
- All JSON files are valid (no syntax errors)
- All keys from English version are present
- Variables like
{{name}}are unchanged - Plural forms follow your language's rules
- Reviewed by at least one other native speaker
- Tested in the UI (if possible)
- Consistent terminology across all files
- Natural, fluent language (not literal translation)
- Appropriate formality level
- Technical terms handled correctly
All contributors are recognized in:
-
CONTRIBUTORS.mdfile - GitHub Contributors page
- App's "About" section (optional)
- Release notes for language additions
Each translation file can include translator credits:
{
"_meta": {
"translators": [
{
"name": "Your Name",
"github": "yourusername",
"email": "[email protected]" // optional
}
],
"lastUpdated": "2026-01-31",
"completionPercent": 100
},
"app": {
// ... translations
}
}Current status of all languages:
| Language | Common | Chat | Settings | Admin | Total |
|---|---|---|---|---|---|
| English (en) | 100% | 100% | 100% | 100% | 100% |
| Spanish (es) | 100% | 100% | 100% | 95% | 98% |
| French (fr) | 100% | 100% | 100% | 95% | 98% |
| German (de) | 100% | 100% | 95% | 90% | 96% |
| Chinese (zh) | 100% | 100% | 90% | 85% | 93% |
| Arabic (ar) | 100% | 95% | 85% | 80% | 90% |
| Japanese (ja) | 100% | 95% | 80% | 75% | 87% |
| Portuguese (pt) | 100% | 95% | 80% | 75% | 87% |
| Russian (ru) | 100% | 95% | 80% | 75% | 87% |
-
Context Questions
- Don't understand a string?
- Need to see it in the UI?
- Ask in the Pull Request comments
-
Technical Issues
- JSON syntax problems?
- Setup issues?
- Testing problems?
- Open an issue or ask in Discussions
-
Translation Discussions
- Join GitHub Discussions
- Connect with other translators
- Discuss terminology
- Share best practices
- ๐ง Email: [email protected]
- ๐ฌ Discord: Join our i18n channel
- ๐ฆ Twitter: @nselfchat
- JSON Editor: jsoneditoronline.org
- JSON Validator: jsonlint.com
- Plural Rules: Unicode CLDR
- Language Codes: ISO 639-1
Check terminology in similar apps:
- Slack
- Discord
- Microsoft Teams
- Telegram
Thank you for contributing to make nself-chat accessible to more people worldwide!
Every translation helps democratize team communication and brings the power of self-hosted, open-source collaboration to more communities.
Your contribution makes a real difference! ๐๐
Ready to start? Create your first Pull Request!
Questions? Join the discussion!