* Initial plan * Initial analysis: understanding locale system issues Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com> * Fix translation types to match actual component usage Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com> * Add comprehensive locale system documentation and fix API route types Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com> * Address code review feedback: improve readability and translate comments to English Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com>
147 lines
4.9 KiB
Markdown
147 lines
4.9 KiB
Markdown
# Directus Integration - Migration Guide
|
|
|
|
## 🎯 Overview
|
|
|
|
This portfolio now has a **hybrid i18n system**:
|
|
- ✅ **JSON Files** (Primary) → All translations work from `messages/*.json` files
|
|
- ✅ **Directus CMS** (Optional) → Can override translations dynamically without rebuilds
|
|
|
|
**Important**: Directus is **optional**. The app works perfectly fine without it using JSON fallbacks.
|
|
|
|
## 📁 New File Structure
|
|
|
|
### Core Infrastructure
|
|
- `lib/directus.ts` - REST Client for Directus (uses `de-DE`, `en-US` locale codes)
|
|
- `lib/i18n-loader.ts` - Loads texts with Fallback Chain
|
|
- `lib/translations-loader.ts` - Batch loader for all sections (cleaned up to match actual usage)
|
|
- `types/translations.ts` - TypeScript types for all translation objects (fixed to match components)
|
|
|
|
### Components
|
|
All component wrappers properly load and pass translations to client components.
|
|
|
|
## 🔄 How It Works
|
|
|
|
### Without Directus (Default)
|
|
```
|
|
Component → useTranslations("nav") → JSON File (messages/en.json)
|
|
```
|
|
|
|
### With Directus (Optional)
|
|
```
|
|
Server Component → getNavTranslations(locale)
|
|
→ Try Directus API (de-DE/en-US)
|
|
→ If not found: JSON File (de/en)
|
|
→ Props to Client Component
|
|
```
|
|
|
|
## 🗄️ Directus Setup (Optional)
|
|
|
|
Only set this up if you want to edit translations through a CMS without rebuilding the app.
|
|
|
|
### 1. Environment Variables
|
|
|
|
Add to `.env.local`:
|
|
```bash
|
|
DIRECTUS_URL=https://cms.example.com
|
|
DIRECTUS_STATIC_TOKEN=your_token_here
|
|
```
|
|
|
|
**If these are not set**, the system will skip Directus and use JSON files only.
|
|
|
|
### 2. Collection: `messages`
|
|
|
|
Create a `messages` collection in Directus with these fields:
|
|
- `key` (String, required) - e.g., "nav.home"
|
|
- `translations` (Translations) - Directus native translations feature
|
|
- Configure languages: `en-US` and `de-DE`
|
|
|
|
**Note**: Keys use dot notation (`nav.home`) but locales use dashes (`en-US`, `de-DE`).
|
|
|
|
### 3. Permissions
|
|
|
|
Grant **Public** role read access to `messages` collection.
|
|
|
|
## 📝 Translation Keys
|
|
|
|
See `docs/LOCALE_SYSTEM.md` for the complete list of translation keys and their structure.
|
|
|
|
All keys are organized hierarchically:
|
|
- `nav.*` - Navigation items
|
|
- `home.hero.*` - Hero section
|
|
- `home.about.*` - About section
|
|
- `home.projects.*` - Projects section
|
|
- `home.contact.*` - Contact form and info
|
|
- `footer.*` - Footer content
|
|
- `consent.*` - Privacy consent banner
|
|
|
|
## 🎨 Rich Text Content
|
|
|
|
For longer content that needs formatting (bold, italic, lists), use the `content_pages` collection:
|
|
|
|
### Collection: `content_pages` (Optional)
|
|
|
|
Fields:
|
|
- `slug` (String, unique) - e.g., "home-hero"
|
|
- `locale` (String) - `en` or `de`
|
|
- `title` (String)
|
|
- `content` (Rich Text or Long Text)
|
|
|
|
Examples:
|
|
- `home-hero` - Hero section description
|
|
- `home-about` - About section content
|
|
- `home-contact` - Contact intro text
|
|
|
|
Components fetch these via `/api/content/page` and render using `RichTextClient`.
|
|
|
|
## 🔍 Fallback Chain
|
|
|
|
For every translation key, the system searches in this order:
|
|
|
|
1. **Directus** (if configured) in requested locale (e.g., `de-DE`)
|
|
2. **Directus** in English fallback (e.g., `en-US`)
|
|
3. **JSON file** in requested locale (e.g., `messages/de.json`)
|
|
4. **JSON file** in English (e.g., `messages/en.json`)
|
|
5. **Key itself** as last resort (e.g., returns `"nav.home"`)
|
|
|
|
## ✅ What Was Fixed
|
|
|
|
Previous issues that have been resolved:
|
|
|
|
1. ✅ **Type mismatches** - All translation types now match actual component usage
|
|
2. ✅ **Unused fields** - Removed translation keys that were never used (like `hero.greeting`, `hero.name`)
|
|
3. ✅ **Wrong structure** - Fixed `AboutTranslations` structure (removed fake `interests` nesting)
|
|
4. ✅ **Missing keys** - Aligned loaders with JSON files and actual component requirements
|
|
5. ✅ **Confusing comments** - Removed misleading comments in `translations-loader.ts`
|
|
|
|
## 🎯 Best Practices
|
|
|
|
1. **Always maintain JSON files** - Even if using Directus, keep JSON files as fallback
|
|
2. **Use types** - TypeScript types ensure correct usage
|
|
3. **Test without Directus** - App should work perfectly without CMS configured
|
|
4. **Rich text for formatting** - Use `content_pages` for content that needs bold/italic/lists
|
|
5. **JSON for UI labels** - Use JSON/messages for short UI strings like buttons and labels
|
|
|
|
## 🐛 Troubleshooting
|
|
|
|
### Directus not configured
|
|
**This is normal!** The app works fine. All translations come from JSON files.
|
|
|
|
### Want to use Directus?
|
|
1. Set up `DIRECTUS_URL` and `DIRECTUS_STATIC_TOKEN`
|
|
2. Create `messages` collection
|
|
3. Add your translations
|
|
4. They will override JSON values
|
|
|
|
### Translation not showing?
|
|
Check in this order:
|
|
1. Does key exist in `messages/en.json`?
|
|
2. Is the key spelled correctly?
|
|
3. Is component using correct namespace?
|
|
|
|
## 📚 Further Reading
|
|
|
|
- **Complete locale documentation**: `docs/LOCALE_SYSTEM.md`
|
|
- **Directus setup checklist**: `DIRECTUS_CHECKLIST.md`
|
|
- **Operations guide**: `docs/OPERATIONS.md`
|
|
|