i18n & Localization
Internationalization (i18n) and Localization (L10n) best practices.
- Core Concepts
Term Meaning
i18n Internationalization - making app translatable
L10n Localization - actual translations
Locale Language + Region (en-US, tr-TR)
RTL Right-to-left languages (Arabic, Hebrew)
- When to Use i18n
Project Type i18n Needed?
Public web app ✅ Yes
SaaS product ✅ Yes
Internal tool ⚠️ Maybe
Single-region app ⚠️ Consider future
Personal project ❌ Optional
- Implementation Patterns
React (react-i18next)
import { useTranslation } from 'react-i18next';
function Welcome() { const { t } = useTranslation(); return <h1>{t('welcome.title')}</h1>; }
Next.js (next-intl)
import { useTranslations } from 'next-intl';
export default function Page() { const t = useTranslations('Home'); return <h1>{t('title')}</h1>; }
Python (gettext)
from gettext import gettext as _
print(_("Welcome to our app"))
- File Structure
locales/ ├── en/ │ ├── common.json │ ├── auth.json │ └── errors.json ├── tr/ │ ├── common.json │ ├── auth.json │ └── errors.json └── ar/ # RTL └── ...
- Best Practices
DO ✅
-
Use translation keys, not raw text
-
Namespace translations by feature
-
Support pluralization
-
Handle date/number formats per locale
-
Plan for RTL from the start
-
Use ICU message format for complex strings
DON'T ❌
-
Hardcode strings in components
-
Concatenate translated strings
-
Assume text length (German is 30% longer)
-
Forget about RTL layout
-
Mix languages in same file
- Common Issues
Issue Solution
Missing translation Fallback to default language
Hardcoded strings Use linter/checker script
Date format Use Intl.DateTimeFormat
Number format Use Intl.NumberFormat
Pluralization Use ICU message format
- RTL Support
/* CSS Logical Properties / .container { margin-inline-start: 1rem; / Not margin-left / padding-inline-end: 1rem; / Not padding-right */ }
[dir="rtl"] .icon { transform: scaleX(-1); }
- Checklist
Before shipping:
-
All user-facing strings use translation keys
-
Locale files exist for all supported languages
-
Date/number formatting uses Intl API
-
RTL layout tested (if applicable)
-
Fallback language configured
-
No hardcoded strings in components
Script
Script Purpose Command
scripts/i18n_checker.py
Detect hardcoded strings & missing translations python scripts/i18n_checker.py <project_path>