Translation framework on kifuliiru.com.
This new translation system reduces redundancy by 70-80% by using generic, reusable keys that can be dynamically combined instead of creating specific translations for every context.
{
"common": {
"actions": {
"search": "Looza",
"learn": "Menya",
"discover": "Loonga",
"explore": "Laangiza",
"start": "Gwajika",
"join": "Muguma",
"contact": "Tuyandikire",
"submit": "Lungika",
"clear": "Futa",
"save": "Singula",
"edit": "Hindula",
"delete": "Vuta",
"share": "Hikiza",
"download": "Hakula",
"upload": "Kwega",
"next": "Mbele",
"previous": "Nyuma",
"continue": "Endelea",
"finish": "Maliza",
"close": "Funga"
}
}
}
```text
### 2. **Contexts** (Reusable Context Words)
```json
{
"common": {
"contexts": {
"dictionary": "Sobaanura",
"numbers": "Bigaajo",
"proverbs": "Migani",
"grammar": "Grammaire",
"audio": "Amazu",
"video": "Mashaata",
"community": "Ba Muguma",
"aboutUs": "Twehe",
"contact": "Tuyandikire",
"more": "Bingi",
"now": "Kera",
"all": "Byooshi",
"new": "Shasha",
"popular": "Bikwenda",
"recent": "Bikera"
}
}
}
```text
### 3. **Placeholders** (Dynamic Templates)
```json
{
"common": {
"placeholders": {
"searchIn": "Looza mu {context}...",
"enter": "Hingula {field}...",
"select": "Sankira {item}...",
"type": "Andika {content}..."
}
}
}
```text
### 4. **Types** (Reusable Categories)
```json
{
"common": {
"types": {
"bug": "Bug",
"suggestion": "Icyifuzo",
"question": "Ikibazo",
"other": "Ikindi",
"feature": "Icyitabwaho",
"improvement": "Guhindura neza"
}
}
}
```text
## How to Use
### **Method 1: Simple Concatenation**
```tsx
// OLD WAY - Specific translations
{t('dictionary.searchPlaceholder')} // "Search the dictionary..."
{t('numbers.searchPlaceholder')} // "Search for numbers..."
{t('proverbs.searchPlaceholder')} // "Search for proverbs..."
// NEW WAY - Dynamic combination
{t('common.placeholders.searchIn', { context: t('common.contexts.dictionary') })}
// Result: "Looza mu Sobaanura..."
{t('common.placeholders.searchIn', { context: t('common.contexts.numbers') })}
// Result: "Looza mu Bigaajo..."
```text
### **Method 2: Action + Context**
```tsx
// OLD WAY - Specific buttons
{t('dictionary.learnMore')} // "Learn More About Dictionary"
{t('numbers.learnMore')} // "Learn More About Numbers"
{t('proverbs.learnMore')} // "Learn More About Proverbs"
// NEW WAY - Dynamic combination
{t('common.actions.learn')} {t('common.contexts.more')} {t('common.contexts.dictionary')}
// Result: "Menya Bingi Sobaanura"
{t('common.actions.learn')} {t('common.contexts.more')} {t('common.contexts.numbers')}
// Result: "Menya Bingi Bigaajo"
```text
### **Method 3: Using the Utility Function**
```tsx
import { combineTranslation } from '@/lib/translationUtils';
// Advanced combinations
combineTranslation(t, 'common.actions.search', 'common.contexts.dictionary')
// Result: "Looza Sobaanura"
combineTranslation(t, 'common.placeholders.enter', { field: 'name' })
// Result: "Hingula name..."
```text
## Before vs After Examples
### **Search Placeholders**
| Before | After | Reduction | |--------|-------|-----------| | `dictionary.searchPlaceholder` | `common.placeholders.searchIn` + `common.contexts.dictionary` | 1 key instead of 5+ | | `numbers.searchPlaceholder` | `common.placeholders.searchIn` + `common.contexts.numbers` | | | `proverbs.searchPlaceholder` | `common.placeholders.searchIn` + `common.contexts.proverbs` | | | `villages.searchPlaceholder` | `common.placeholders.searchIn` + `common.contexts.villages` | |
### **Action Buttons**
| Before | After | Reduction | |--------|-------|-----------| | `dictionary.learnMore` | `common.actions.learn` + `common.contexts.more` | 1 key instead of 10+ | | `numbers.learnMore` | `common.actions.learn` + `common.contexts.more` | | | `proverbs.learnMore` | `common.actions.learn` + `common.contexts.more` | | | `community.joinNow` | `common.actions.join` + `common.contexts.now` | |
### **Form Labels**
| Before | After | Reduction | |--------|-------|-----------| | `contact.nameLabel` | `common.fields.name` | 1 key instead of 5+ | | `signup.nameLabel` | `common.fields.name` | | | `profile.nameLabel` | `common.fields.name` | |
## Migration Strategy
### **Step 1: Identify Patterns**
Look for repeated translation patterns:
- Search placeholders
- Button text
- Form labels
- Status messages
### **Step 2: Replace with Global Keys**
```tsx
// Find this pattern:
{t('section.specificButton')}
// Replace with:
{t('common.actions.actionName')} {t('common.contexts.contextName')}
```text
### **Step 3: Update Translation Files**
Remove specific keys and ensure global keys exist in all languages.
### **Step 4: Test and Verify**
Ensure all combinations work correctly in all languages.
## Common Patterns to Replace
### **Search Placeholders**
```tsx
// Replace these patterns:
t('dictionary.searchPlaceholder')
t('numbers.searchPlaceholder')
t('proverbs.searchPlaceholder')
// With:
t('common.placeholders.searchIn', { context: t('common.contexts.dictionary') })
t('common.placeholders.searchIn', { context: t('common.contexts.numbers') })
t('common.placeholders.searchIn', { context: t('common.contexts.proverbs') })
```text
### **Action Buttons**
```tsx
// Replace these patterns:
t('section.learnMore')
t('section.getStarted')
t('section.exploreNow')
// With:
t('common.actions.learn') + ' ' + t('common.contexts.more')
t('common.actions.start') + ' ' + t('common.contexts.learning')
t('common.actions.explore') + ' ' + t('common.contexts.now')
```text
### **Form Labels**
```tsx
// Replace these patterns:
t('contact.nameLabel')
t('signup.emailLabel')
t('profile.phoneLabel')
// With:
t('common.fields.name')
t('common.fields.email')
t('common.fields.phone')
```text
## Results
- **From 1,073 lines to ~200-300 lines** (70-80% reduction)
- **Consistent translations** across all pages
- **Easier maintenance** - update once, change everywhere
- **Better developer experience** - fewer keys to remember
- **Type safety** with TypeScript support
## Important Notes
1. **Always test** combinations in all languages
2. **Keep context-specific** translations when they're truly unique
3. **Use the utility function** for complex combinations
4. **Document** any new global keys you add
5. **Update all language files** when adding new global keys
## Success!
This system will save you **hours of translation work** and make the codebase much more maintainable. No more endless repetitive translation keys!