diff --git a/docs/i18n/README.md b/docs/i18n/README.md new file mode 100644 index 0000000..08cebd2 --- /dev/null +++ b/docs/i18n/README.md @@ -0,0 +1,247 @@ +# 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 ( +
+

{t('nav.home')}

+

{t('siteDescription')}

+
+ ); +} +``` + +### 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 ; +``` + +## 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