6.9 KiB
Internationalization (i18n) Documentation
Complete guide to the multi-language support system in the portfolio application.
Overview
This portfolio supports 3 languages with full internationalization:
| Language | Code | Flag | Region |
|---|---|---|---|
| German (default) | de |
🇩🇪 | Germany |
| English | en |
🇬🇧 | United States |
| Serbian | sr |
🇷🇸 | Serbia |
Tech Stack
- next-intl - Next.js internationalization library
- JSON-based translations - Simple, maintainable translation files
- Type-safe locale handling - TypeScript ensures locale consistency
- SEO optimized - Hreflang tags, Content-Language headers, localized metadata
Key Features
- ✅ Automatic locale detection from URL path
- ✅ Fallback to default locale (German)
- ✅ Server-side translation loading
- ✅ Type-safe locale validation
- ✅ SEO-friendly URL structure (
/de/,/en/,/sr/) - ✅ Localized metadata for social sharing
- ✅ Support for nested translation keys
- ✅ Legacy migration path (locales-old)
Quick Start
Using Translations in Components
import { useTranslations } from 'next-intl';
export default function MyComponent() {
const t = useTranslations('common');
return (
<div>
<h1>{t('nav.home')}</h1>
<p>{t('siteDescription')}</p>
</div>
);
}
Adding a New Translation Key
-
Open all three locale files:
src/messages/de.jsonsrc/messages/en.jsonsrc/messages/sr.json
-
Add your key to the same namespace in each file:
{
"common": {
"actions": {
"newAction": "Neue Aktion" // de
"newAction": "New Action" // en
"newAction": "Nova Akcija" // sr
}
}
}
- Use it in your component:
const t = useTranslations('common.actions');
return <button>{t('newAction')}</button>;
Documentation Structure
This documentation is organized into the following sections:
📁 Directory Structure & Organization
Learn about the file organization, active vs. legacy systems, and configuration files
Topics covered:
src/i18n/- Configuration filessrc/messages/- Active JSON translation filessrc/i18n/locales-old/- Legacy TypeScript translations (deprecated)config.ts- Locale metadata and settingsrequest.ts- next-intl integration
🔑 Adding Translation Keys
Step-by-step guide to adding and managing translations
Topics covered:
- JSON structure and namespaces
- Nested translation keys
- Adding keys across all locales
- Code examples using
useTranslations()- Best practices for key naming
⚙️ Configuration & Setup
Understanding request.ts and next-intl integration
Topics covered:
getRequestConfig()function- Locale validation and fallback logic
- Dynamic message loading
createNextIntlPlugin()in next.config.ts- Server-side vs. client-side translations
🌐 Locale Configuration & Metadata
Detailed breakdown of locale settings and SEO data
Topics covered:
- Locales array and default locale
- Locale names and flags
- Metadata for hreflang and Open Graph
- SEO keywords per locale
- Currency and territory settings
🔍 SEO & Hreflang Implementation
How multilingual SEO is implemented
Topics covered:
- Hreflang tags in layout.tsx
- alternates.languages configuration
- Content-Language HTTP headers
- Localized meta tags and Open Graph
- Sitemap generation for multiple locales
📦 Legacy Migration (locales-old)
Understanding the deprecated TypeScript-based translation system
Topics covered:
- What locales-old contains
- Why the migration happened
- Do NOT use these files
- Migration from TypeScript to JSON
- Safe removal considerations
🛤️ Routing & URL Structure
How locale-based routing works with Next.js App Router
Topics covered:
[locale]dynamic route segment- URL patterns:
/de/,/en/,/sr/- Locale detection in middleware
generateStaticParams()for static generation- Locale switching and redirects
💡 Usage Examples & Best Practices
Practical examples and common patterns
Topics covered:
useTranslations()hook patterns- Accessing nested keys
- Formatting dates and numbers
- Pluralization (if implemented)
- Common pitfalls and solutions
- Performance considerations
Architecture Overview
Portfolio i18n System
│
├── Configuration Layer
│ ├── src/i18n/config.ts # Locale definitions & metadata
│ └── src/i18n/request.ts # next-intl integration
│
├── Translation Files (Active)
│ ├── src/messages/de.json # German translations
│ ├── src/messages/en.json # English translations
│ └── src/messages/sr.json # Serbian translations
│
├── Legacy System (Deprecated)
│ └── src/i18n/locales-old/ # Old TypeScript translations
│
├── Routing Layer
│ ├── src/app/[locale]/layout.tsx # Locale-based layout
│ ├── src/middleware.ts # Locale detection
│ └── next.config.ts # createNextIntlPlugin
│
└── Application Layer
└── Components using useTranslations()
Translation File Structure
Current structure of active translation files:
{
"meta": {
"site": { ... },
"author": { ... },
"social": { ... }
},
"common": {
"siteTitle": "...",
"nav": { ... },
"actions": { ... },
"errors": { ... },
"cookies": { ... }
},
"home": { ... },
"about": { ... },
"portfolio": { ... },
"blog": { ... },
"contact": { ... }
}
Supported Locales
| Locale | Language | hreflang | OG Locale | Currency | Region |
|---|---|---|---|---|---|
de |
Deutsch | de-DE | de_DE | EUR | Germany |
en |
English | en-US | en_US | USD | United States |
sr |
Srpski | sr-RS | sr_RS | RSD | Serbia |
Important Notes
⚠️ Legacy System: The src/i18n/locales-old/ directory contains deprecated TypeScript-based translations from a previous implementation. Do NOT use these files. All new translations should go in src/messages/*.json.
✅ Active System: Use only the JSON files in src/messages/ for all translation work.
🔒 Type Safety: The locale type is derived from the locales array in config.ts, ensuring compile-time validation of locale codes.
🌍 Default Locale: German (de) is the default locale. Invalid or missing locale parameters will fallback to German.
Getting Help
- Check specific sections above for detailed topics
- Review code examples in the pattern files
- Examine existing translation keys in
src/messages/de.json - Look at component usage in
src/app/[locale]/page.tsx
Framework: next-intl + Next.js 15 App Router Default Locale: German (de) Supported Locales: de, en, sr Translation Format: JSON