248 lines
6.9 KiB
Markdown
248 lines
6.9 KiB
Markdown
# 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
|
|
|
|
```tsx
|
|
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
|
|
|
|
1. Open all three locale files:
|
|
- `src/messages/de.json`
|
|
- `src/messages/en.json`
|
|
- `src/messages/sr.json`
|
|
|
|
2. Add your key to the same namespace in each file:
|
|
|
|
```json
|
|
{
|
|
"common": {
|
|
"actions": {
|
|
"newAction": "Neue Aktion" // de
|
|
"newAction": "New Action" // en
|
|
"newAction": "Nova Akcija" // sr
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
3. Use it in your component:
|
|
|
|
```tsx
|
|
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 files
|
|
> - `src/messages/` - Active JSON translation files
|
|
> - `src/i18n/locales-old/` - Legacy TypeScript translations (deprecated)
|
|
> - `config.ts` - Locale metadata and settings
|
|
> - `request.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:
|
|
|
|
```json
|
|
{
|
|
"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
|